1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
4 * Copyright (C) 2007 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include <abstract/aacore.h>
24 #include "nsIGenericFactory.h"
25 #include "nsComponentManagerUtils.h"
26 #include "nsArrayUtils.h"
29 #include <unstable/mozIStorageConnection.h>
30 #include <abstract/cxxunit/nsCxxUnit.h>
31 #include <abstract/cxxunit/nsITest.h>
32 #include <abstract/cxxunit/nsITestRunner.h>
34 /* Project includes */
35 #include <abstract/base/aaIResource.h>
36 #include <abstract/base/aaIFact.h>
37 #include <abstract/base/aaIFlow.h>
38 #include <abstract/base/aaIQuote.h>
39 #include <abstract/base/aaITransaction.h>
40 #include <abstract/base/aaIBalance.h>
41 #include <abstract/storage/aaISession.h>
42 #include <abstract/storage/aaBaseLoaders.h>
43 #include <abstract/storage/aaAccountLoaders.h>
44 #include <abstract/storage/aaILoadQuery.h>
45 #include "aaStorageTest.h"
46 #include "aaSaveTransaction.h"
47 /* XXX _acc This is a temporary hack to acquire connection
48 * It has to be replaced with a 'chart'
50 #include "aaSession.h"
52 #define AA_ACCOUNT_TEST_CID \
53 {0x9f3b3e19, 0x2f06, 0x4a75, {0xbc, 0xb8, 0xd7, 0xd3, 0x5c, 0xaf, 0x9d, 0x36}}
54 #define AA_ACCOUNT_TEST_CONTRACT_ID "@aasii.org/storage/unit-account;1"
56 class aaAccountTest
: public nsITest
60 virtual ~aaAccountTest() {;}
65 nsCOMPtr
<aaISession
> mSession
;
66 nsCOMPtr
<nsIArray
> mFlows
;
67 nsCOMPtr
<nsIArray
> mResources
;
68 nsCOMPtr
<aaIFact
> mPendingFact
;
73 nsresult
testEmptyBalance(nsITestRunner
*aTestRunner
);
74 nsresult
testPendingFacts(nsITestRunner
*aTestRunner
);
75 nsresult
testQuote(nsITestRunner
*aTestRunner
);
76 nsresult
testTransaction(nsITestRunner
*aTestRunner
);
77 nsresult
testUpdateTransaction(nsITestRunner
*aTestRunner
);
78 nsresult
testReplaceTransaction(nsITestRunner
*aTestRunner
);
81 NS_IMPL_ISUPPORTS1(aaAccountTest
, nsITest
);
86 RAII(aaAccountTest
*t
);
96 aaAccountTest::Test(nsITestRunner
*aTestRunner
)
99 if (NS_FAILED( res
.status
)) {
100 aTestRunner
->AddError(nsITestRunner::errorJS
, \
101 AA_ACCOUNT_TEST_CONTRACT_ID
" not initialized");
102 return NS_ERROR_NOT_INITIALIZED
;
104 testEmptyBalance(aTestRunner
);
105 testPendingFacts(aTestRunner
);
106 testQuote(aTestRunner
);
107 testTransaction(aTestRunner
);
108 testUpdateTransaction(aTestRunner
);
109 testReplaceTransaction(aTestRunner
);
115 testFact(nsITestRunner
*cxxUnitTestRunner
, aaIFact
*node
, PRInt64 fromFlowId
,
116 PRInt64 toFlowId
, double sum
)
119 PRBool equals
= PR_TRUE
;
121 nsCOMPtr
<aaIFlow
> flow
;
123 node
->GetTakeFrom(getter_AddRefs( flow
));
126 if (NS_UNLIKELY( id
!= fromFlowId
)) {
128 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'fact.takeFrom.id' is wrong" );
130 } else if (NS_UNLIKELY( fromFlowId
!= 0 )) {
132 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'fact.takeFrom.id' is wrong" );
135 node
->GetGiveTo(getter_AddRefs( flow
));
138 if (NS_UNLIKELY( id
!= toFlowId
)) {
140 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'fact.giveTo.id' is wrong" );
142 } else if (NS_UNLIKELY( toFlowId
!= 0 )) {
144 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'fact.giveTo.id' is wrong" );
148 rv
= node
->GetAmount(&amount
);
150 if (diff
> 0.0001 || diff
< -0.0001) {
152 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'fact.amount' is wrong" );
159 testBalance(nsITestRunner
*cxxUnitTestRunner
, aaIBalance
*node
, PRInt64 flowId
,
160 PRInt64 resourceId
, double amount
, double value
)
163 PRBool equals
= PR_TRUE
;
164 if (NS_UNLIKELY( ! node
)) {
165 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'balance' is null");
168 nsCOMPtr
<aaIFlow
> flow
;
169 rv
= node
->GetFlow(getter_AddRefs( flow
));
170 NS_TEST_ASSERT_MSG(flow
, " 'balance.flow' is null");
172 if (NS_LIKELY( flow
)) {
174 if (NS_UNLIKELY( id
!= flowId
) ) {
176 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'balance.flow.id' is wrong");
182 nsCOMPtr
<aaIResource
> resource
;
183 rv
= node
->GetResource(getter_AddRefs( resource
));
184 NS_TEST_ASSERT_MSG(resource
, " 'balance.resource' is null" );
185 if (NS_LIKELY( resource
)) {
186 resource
->GetId(&id
);
187 if (NS_UNLIKELY( id
!= resourceId
) ) {
189 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'balance.resource.id' is wrong");
196 node
->GetAmount(&sum
);
198 if (diff
> 0.0001 || diff
< -0.0001) {
200 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'balance.amount' is wrong");
203 node
->GetValue(&sum
);
205 if (diff
> 0.0001 || diff
< -0.0001) {
207 NS_TEST_ASSERT_MSG(PR_FALSE
, " 'balance.value' is wrong");
213 RAII::RAII(aaAccountTest
*t
)
214 :status(PR_FALSE
), test(nsnull
)
217 nsCOMPtr
<aaISession
> session(do_CreateInstance(AA_SESSION_CONTRACT_ID
, &rv
));
218 if (NS_UNLIKELY( ! session
))
221 nsCOMPtr
<nsIArray
> flows
;
222 rv
= session
->Load(AA_LOADFLOW_CONTRACT_ID
, getter_AddRefs( flows
));
223 if (NS_UNLIKELY( ! flows
))
226 nsCOMPtr
<nsIArray
> resources
;
227 rv
= session
->Load(AA_LOADRESOURCE_CONTRACT_ID
, getter_AddRefs( resources
));
228 if (NS_UNLIKELY( ! resources
))
233 test
->mSession
= session
;
234 test
->mFlows
= flows
;
235 test
->mResources
= resources
;
240 test
->mPendingFact
= nsnull
;
241 test
->mResources
= nsnull
;
242 test
->mFlows
= nsnull
;
243 test
->mSession
= nsnull
;
247 /* Private methods */
249 aaAccountTest::testEmptyBalance(nsITestRunner
*aTestRunner
)
252 NS_TEST_BEGIN(aTestRunner
);
253 aaSession
*session
= static_cast<aaSession
*>(mSession
.get());
254 NS_TEST_ASSERT_MSG(session
, "[empty balance] 'session' cast" );
255 NS_ENSURE_TRUE(session
, NS_ERROR_UNEXPECTED
);
257 nsCOMPtr
<aaILoadQuery
> loader(do_CreateInstance(
258 AA_LOADBALANCE_CONTRACT_ID
, session
->mConnection
, &rv
));
259 NS_TEST_ASSERT_MSG(loader
, "[empty balance] query instance creation" );
260 NS_ENSURE_TRUE(loader
, rv
);
262 nsCOMPtr
<nsIArray
> set
;
263 rv
= loader
->Load(getter_AddRefs( set
));
264 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[empty balance] loading");
265 NS_TEST_ASSERT_MSG(set
, "[empty balance] result set not loaded" );
266 NS_ENSURE_TRUE(set
, rv
);
269 set
->GetLength(&count
);
270 NS_TEST_ASSERT_MSG(count
== 0, "[empty balance] wrong flow count");
276 aaAccountTest::testPendingFacts(nsITestRunner
*aTestRunner
)
279 NS_TEST_BEGIN(aTestRunner
);
280 aaSession
*session
= static_cast<aaSession
*>(mSession
.get());
281 NS_TEST_ASSERT_MSG(session
, "[pending facts] 'session' cast" );
282 NS_ENSURE_TRUE(session
, NS_ERROR_UNEXPECTED
);
284 nsCOMPtr
<aaILoadQuery
> loader(do_CreateInstance(
285 AA_LOADPENDINGFACTS_CONTRACT_ID
, session
->mConnection
, &rv
));
286 NS_TEST_ASSERT_MSG(loader
, "[pending facts] query instance creation" );
287 NS_ENSURE_TRUE(loader
, rv
);
289 nsCOMPtr
<nsIArray
> set
;
290 rv
= loader
->Load(getter_AddRefs( set
));
291 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[pending facts] loading");
292 NS_TEST_ASSERT_MSG(set
, "[pending facts] result set not loaded" );
293 NS_ENSURE_TRUE(set
, rv
);
296 set
->GetLength(&count
);
297 NS_TEST_ASSERT_MSG(count
== 3, "[pending facts] wrong flow count");
299 mPendingFact
= do_QueryElementAt(set
, 0, &rv
);
300 NS_TEST_ASSERT_MSG(mPendingFact
, "[pending facts] 1st fact not loaded" );
302 NS_TEST_ASSERT_MSG(testFact(aTestRunner
, mPendingFact
, 2, 3,
303 AA_EVENT_AMOUNT_2
), "[pending facts] 1st fact is wrong");
308 aaAccountTest::testQuote(nsITestRunner
*aTestRunner
)
311 NS_TEST_BEGIN(aTestRunner
);
312 nsCOMPtr
<aaIQuote
> node(do_CreateInstance("@aasii.org/base/quote;1", &rv
));
313 NS_TEST_ASSERT_MSG(node
, "[quote] instance not created" );
314 NS_ENSURE_TRUE(node
, rv
);
316 nsCOMPtr
<aaIResource
> rub
= do_QueryElementAt(mResources
, 0, &rv
);
317 node
->SetResource( rub
);
319 /* Set time to 2007-08-29 */
320 PRExplodedTime tm
= {0,0,0,12,29,7,2007};
321 node
->SetTime(PR_ImplodeTime(&tm
));
324 rv
= mSession
->Save( node
, nsnull
);
325 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[quote] saving");
327 aaSession
*session
= static_cast<aaSession
*>(mSession
.get());
328 NS_TEST_ASSERT_MSG(session
, "[quote] 'session' cast" );
329 NS_ENSURE_TRUE(session
, NS_ERROR_UNEXPECTED
);
331 nsCOMPtr
<aaILoadQuery
> loader(do_CreateInstance(
332 AA_LOADQUOTE_CONTRACT_ID
, session
->mConnection
, &rv
));
333 NS_TEST_ASSERT_MSG(loader
, "[quote] query instance creation" );
334 NS_ENSURE_TRUE(loader
, rv
);
336 nsCOMPtr
<nsIArray
> set
;
337 rv
= loader
->Load(getter_AddRefs( set
));
338 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[quote] loading");
339 NS_TEST_ASSERT_MSG(set
, "[quote] result set not loaded" );
340 NS_ENSURE_TRUE(set
, rv
);
343 set
->GetLength(&count
);
344 NS_TEST_ASSERT_MSG(count
== 1, "[quote] wrong quote count");
346 nsCOMPtr
<aaIQuote
> quote
= do_QueryElementAt(set
, 0, &rv
);
347 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[quote] quering 1st quote");
348 NS_TEST_ASSERT_MSG(quote
, "[quote] 1st quote not loaded" );
349 NS_ENSURE_TRUE(quote
, NS_ERROR_FAILURE
);
351 nsCOMPtr
<aaIResource
> obj
;
356 quote
->GetResource(getter_AddRefs( obj
));
357 if (NS_LIKELY( obj
)) {
358 obj
->GetId( &objId
);
359 NS_TEST_ASSERT_MSG(objId
== 1, "[quote] wrong resource id");
361 NS_TEST_ASSERT_MSG(obj
, "[quote] resource is null");
363 quote
->GetTime( &time
);
364 NS_TEST_ASSERT_MSG(time
== PR_ImplodeTime(&tm
), "[quote] wrong start time");
365 quote
->GetRate( &rate
);
366 NS_TEST_ASSERT_MSG(rate
< 1.00009 && rate
> 0.99991, "[quote] wrong rate");
372 aaAccountTest::testTransaction(nsITestRunner
*aTestRunner
)
375 NS_TEST_BEGIN(aTestRunner
);
376 aaSession
*session
= static_cast<aaSession
*>(mSession
.get());
377 NS_TEST_ASSERT_MSG(session
, "[transaction] 'session' cast" );
378 NS_ENSURE_TRUE(session
, NS_ERROR_UNEXPECTED
);
380 nsCOMPtr
<aaISaveQuery
> saver(do_CreateInstance(
381 AA_SAVETRANSACTION_CONTRACT_ID
, session
->mConnection
, &rv
));
382 NS_TEST_ASSERT_MSG(saver
, "[transaction] query instance creation" );
383 NS_ENSURE_TRUE(saver
, rv
);
385 nsCOMPtr
<aaITransaction
> node(do_CreateInstance(
386 "@aasii.org/base/transaction;1", &rv
));
387 NS_TEST_ASSERT_MSG(node
, "[transaction] instance not created" );
388 NS_ENSURE_TRUE(node
, rv
);
390 node
->SetFact(mPendingFact
);
392 rv
= saver
->Save(node
, nsnull
);
393 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[transaction] saving" );
395 nsCOMPtr
<nsIArray
> set
;
396 rv
= mSession
->Load(AA_LOADBALANCE_CONTRACT_ID
, getter_AddRefs( set
));
397 NS_TEST_ASSERT_MSG(set
, "[transaction] result set not loaded" );
398 NS_ENSURE_TRUE(set
, rv
);
401 set
->GetLength(&count
);
402 NS_TEST_ASSERT_MSG(count
== 2, "[transaction] wrong flow count");
404 nsCOMPtr
<aaIBalance
> balance(do_QueryElementAt(set
, 0));
405 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 2, 2, AA_EVENT_AMOUNT_2
406 / AA_FLOW_SHARE_RATE
, AA_EVENT_AMOUNT_2
),
407 "[transaction] flow2 is wrong");
409 balance
= do_QueryElementAt(set
, 1);
410 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 3, 1, AA_EVENT_AMOUNT_2
,
411 AA_EVENT_AMOUNT_2
), "[transaction] flow3 is wrong");
413 rv
= mSession
->Load(AA_LOADPENDINGFACTS_CONTRACT_ID
, getter_AddRefs( set
));
414 NS_TEST_ASSERT_MSG(set
, "[transaction] fact set not loaded" );
415 NS_ENSURE_TRUE(set
, rv
);
417 set
->GetLength(&count
);
418 NS_TEST_ASSERT_MSG(count
== 2, "[transaction] wrong fact count");
420 mPendingFact
= do_QueryElementAt(set
, 0, &rv
);
421 NS_TEST_ASSERT_MSG(mPendingFact
, "[transaction] pending fact not loaded" );
423 NS_TEST_ASSERT_MSG(testFact(aTestRunner
, mPendingFact
, 1, 3,
424 AA_EVENT_AMOUNT_3
), "[transaction] pending fact is wrong");
429 aaAccountTest::testUpdateTransaction(nsITestRunner
*aTestRunner
)
432 NS_TEST_BEGIN(aTestRunner
);
434 nsCOMPtr
<aaITransaction
> node(do_CreateInstance(
435 "@aasii.org/base/transaction;1", &rv
));
436 NS_TEST_ASSERT_MSG(node
, "[update txn] instance not created" );
437 NS_ENSURE_TRUE(node
, rv
);
439 node
->SetFact(mPendingFact
);
441 rv
= mSession
->Save(node
, nsnull
);
442 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[update txn] saving" );
444 nsCOMPtr
<nsIArray
> set
;
445 rv
= mSession
->Load(AA_LOADBALANCE_CONTRACT_ID
, getter_AddRefs( set
));
446 NS_TEST_ASSERT_MSG(set
, "[update txn] result set not loaded" );
447 NS_ENSURE_TRUE(set
, rv
);
450 set
->GetLength(&count
);
451 NS_TEST_ASSERT_MSG(count
== 3, "[update txn] wrong flow count");
453 nsCOMPtr
<aaIBalance
> balance(do_QueryElementAt(set
, 0));
454 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 2, 2, AA_EVENT_AMOUNT_2
455 / AA_FLOW_SHARE_RATE
, AA_EVENT_AMOUNT_2
),
456 "[update txn] flow2 is wrong");
458 balance
= do_QueryElementAt(set
, 1);
459 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 3, 1, AA_EVENT_AMOUNT_2
460 + AA_EVENT_AMOUNT_3
, AA_EVENT_AMOUNT_2
+ AA_EVENT_AMOUNT_3
),
461 "[update txn] flow3 is wrong");
463 balance
= do_QueryElementAt(set
, 2);
464 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 1, 2, AA_EVENT_AMOUNT_3
465 / AA_FLOW_SHARE_RATE
, AA_EVENT_AMOUNT_3
),
466 "[update txn] flow1 is wrong");
468 rv
= mSession
->Load(AA_LOADPENDINGFACTS_CONTRACT_ID
, getter_AddRefs( set
));
469 NS_TEST_ASSERT_MSG(set
, "[update txn] fact set not loaded" );
470 NS_ENSURE_TRUE(set
, rv
);
472 set
->GetLength(&count
);
473 NS_TEST_ASSERT_MSG(count
== 1, "[update txn] wrong fact count");
475 mPendingFact
= do_QueryElementAt(set
, 0, &rv
);
476 NS_TEST_ASSERT_MSG(mPendingFact
, "[update txn] pending fact not loaded" );
478 NS_TEST_ASSERT_MSG(testFact(aTestRunner
, mPendingFact
, 3, 4,
479 AA_EVENT_AMOUNT_4
), "[update txn] pending fact is wrong");
484 aaAccountTest::testReplaceTransaction(nsITestRunner
*aTestRunner
)
487 NS_TEST_BEGIN(aTestRunner
);
489 nsCOMPtr
<aaITransaction
> node(do_CreateInstance(
490 "@aasii.org/base/transaction;1", &rv
));
491 NS_TEST_ASSERT_MSG(node
, "[replace txn] instance not created" );
492 NS_ENSURE_TRUE(node
, rv
);
494 node
->SetFact(mPendingFact
);
496 rv
= mSession
->Save(node
, nsnull
);
497 NS_TEST_ASSERT_MSG(NS_SUCCEEDED(rv
), "[replace txn] saving" );
499 nsCOMPtr
<nsIArray
> set
;
500 rv
= mSession
->Load(AA_LOADBALANCE_CONTRACT_ID
, getter_AddRefs( set
));
501 NS_TEST_ASSERT_MSG(set
, "[replace txn] result set not loaded" );
502 NS_ENSURE_TRUE(set
, rv
);
505 set
->GetLength(&count
);
506 NS_TEST_ASSERT_MSG(count
== 4, "[replace txn] wrong flow count");
508 nsCOMPtr
<aaIBalance
> balance(do_QueryElementAt(set
, 0));
509 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 2, 2, AA_EVENT_AMOUNT_2
510 / AA_FLOW_SHARE_RATE
, AA_EVENT_AMOUNT_2
),
511 "[replace txn] flow2 is wrong");
513 balance
= do_QueryElementAt(set
, 1);
514 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 1, 2, AA_EVENT_AMOUNT_3
515 / AA_FLOW_SHARE_RATE
, AA_EVENT_AMOUNT_3
),
516 "[replace txn] flow1 is wrong");
518 balance
= do_QueryElementAt(set
, 2);
519 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 3, 1, AA_EVENT_AMOUNT_2
520 + AA_EVENT_AMOUNT_3
- AA_EVENT_AMOUNT_4
, AA_EVENT_AMOUNT_2
521 + AA_EVENT_AMOUNT_3
- AA_EVENT_AMOUNT_4
),
522 "[replace txn] flow3 is wrong");
524 balance
= do_QueryElementAt(set
, 3);
525 NS_TEST_ASSERT_MSG(testBalance(aTestRunner
, balance
, 4, 3, AA_EVENT_AMOUNT_5
,
526 AA_EVENT_AMOUNT_4
), "[replace txn] flow4 is wrong");
528 rv
= mSession
->Load(AA_LOADPENDINGFACTS_CONTRACT_ID
, getter_AddRefs( set
));
529 NS_TEST_ASSERT_MSG(set
, "[replace txn] fact set not loaded" );
530 NS_ENSURE_TRUE(set
, rv
);
532 set
->GetLength(&count
);
533 NS_TEST_ASSERT_MSG(count
== 0, "[replace txn] wrong fact count");
536 /* Boilerplate - factory & module */
537 NS_GENERIC_FACTORY_CONSTRUCTOR(aaAccountTest
)
539 static const nsModuleComponentInfo kComponents
[] =
542 "Account Submodule Unit Test",
544 AA_ACCOUNT_TEST_CONTRACT_ID
,
545 aaAccountTestConstructor
548 NS_IMPL_NSGETMODULE(aaaccountt
, kComponents
)