LCOV - code coverage report
Current view: directory - editor/txmgr/tests - TestTXMgr.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1940 1103 56.9 %
Date: 2012-06-02 Functions: 36 35 97.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Serge Gautherie <sgautherie.bz@free.fr>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "TestHarness.h"
      40                 : 
      41                 : #include "nsITransactionManager.h"
      42                 : #include "nsComponentManagerUtils.h"
      43                 : 
      44                 : static PRInt32 sConstructorCount     = 0;
      45                 : static PRInt32 sDestructorCount      = 0;
      46                 : static PRInt32 *sDestructorOrderArr  = 0;
      47                 : static PRInt32 sDoCount              = 0;
      48                 : static PRInt32 *sDoOrderArr          = 0;
      49                 : static PRInt32 sUndoCount            = 0;
      50                 : static PRInt32 *sUndoOrderArr        = 0;
      51                 : static PRInt32 sRedoCount            = 0;
      52                 : static PRInt32 *sRedoOrderArr        = 0;
      53                 : 
      54                 : // #define ENABLE_DEBUG_PRINTFS 1
      55                 : 
      56                 : PRInt32 sSimpleTestDestructorOrderArr[] = {
      57                 :           2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
      58                 :          16,  17,  18,  19,  20,  21,   1,  22,  23,  24,  25,  26,  27,  28,
      59                 :          29,  30,  31,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,
      60                 :          53,  54,  55,  56,  57,  58,  59,  60,  61,  41,  40,  62,  39,  38,
      61                 :          37,  36,  35,  34,  33,  32,  68,  63,  64,  65,  66,  67,  69,  71,
      62                 :          70,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
      63                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
      64                 :          99, 100, 101, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 131,
      65                 :         130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117,
      66                 :         116, 115, 114, 113, 112 };
      67                 : 
      68                 : PRInt32 sSimpleTestDoOrderArr[] = {
      69                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
      70                 :          15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
      71                 :          29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
      72                 :          43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
      73                 :          57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
      74                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
      75                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
      76                 :          99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
      77                 :         113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
      78                 :         127, 128, 129, 130, 131 };
      79                 : 
      80                 : PRInt32 sSimpleTestUndoOrderArr[] = {
      81                 :          41,  40,  39,  38,  62,  39,  38,  37,  69,  71,  70, 111, 110, 109,
      82                 :         108, 107, 106, 105, 104, 103, 102, 131, 130, 129, 128, 127, 126, 125,
      83                 :         124, 123, 122 };
      84                 : 
      85                 : static PRInt32 sSimpleTestRedoOrderArr[] = {
      86                 :          38,  39,  70 };
      87                 : 
      88                 : PRInt32 sAggregateTestDestructorOrderArr[] = {
      89                 :          14,  13,  12,  11,  10,   9,   8,  21,  20,  19,  18,  17,  16,  15,
      90                 :          28,  27,  26,  25,  24,  23,  22,  35,  34,  33,  32,  31,  30,  29,
      91                 :          42,  41,  40,  39,  38,  37,  36,  49,  48,  47,  46,  45,  44,  43,
      92                 :          56,  55,  54,  53,  52,  51,  50,  63,  62,  61,  60,  59,  58,  57,
      93                 :          70,  69,  68,  67,  66,  65,  64,  77,  76,  75,  74,  73,  72,  71,
      94                 :          84,  83,  82,  81,  80,  79,  78,  91,  90,  89,  88,  87,  86,  85,
      95                 :          98,  97,  96,  95,  94,  93,  92, 105, 104, 103, 102, 101, 100,  99,
      96                 :         112, 111, 110, 109, 108, 107, 106, 119, 118, 117, 116, 115, 114, 113,
      97                 :         126, 125, 124, 123, 122, 121, 120, 133, 132, 131, 130, 129, 128, 127,
      98                 :         140, 139, 138, 137, 136, 135, 134, 147, 146, 145, 144, 143, 142, 141,
      99                 :           7,   6,   5,   4,   3,   2,   1, 154, 153, 152, 151, 150, 149, 148,
     100                 :         161, 160, 159, 158, 157, 156, 155, 168, 167, 166, 165, 164, 163, 162,
     101                 :         175, 174, 173, 172, 171, 170, 169, 182, 181, 180, 179, 178, 177, 176,
     102                 :         189, 188, 187, 186, 185, 184, 183, 196, 195, 194, 193, 192, 191, 190,
     103                 :         203, 202, 201, 200, 199, 198, 197, 210, 209, 208, 207, 206, 205, 204,
     104                 :         217, 216, 215, 214, 213, 212, 211, 294, 293, 292, 291, 290, 289, 288,
     105                 :         301, 300, 299, 298, 297, 296, 295, 308, 307, 306, 305, 304, 303, 302,
     106                 :         315, 314, 313, 312, 311, 310, 309, 322, 321, 320, 319, 318, 317, 316,
     107                 :         329, 328, 327, 326, 325, 324, 323, 336, 335, 334, 333, 332, 331, 330,
     108                 :         343, 342, 341, 340, 339, 338, 337, 350, 349, 348, 347, 346, 345, 344,
     109                 :         357, 356, 355, 354, 353, 352, 351, 364, 363, 362, 361, 360, 359, 358,
     110                 :         371, 370, 369, 368, 367, 366, 365, 378, 377, 376, 375, 374, 373, 372,
     111                 :         385, 384, 383, 382, 381, 380, 379, 392, 391, 390, 389, 388, 387, 386,
     112                 :         399, 398, 397, 396, 395, 394, 393, 406, 405, 404, 403, 402, 401, 400,
     113                 :         413, 412, 411, 410, 409, 408, 407, 420, 419, 418, 417, 416, 415, 414,
     114                 :         427, 426, 425, 424, 423, 422, 421, 287, 286, 285, 284, 283, 282, 281,
     115                 :         280, 279, 278, 277, 276, 275, 274, 434, 433, 432, 431, 430, 429, 428,
     116                 :         273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260,
     117                 :         259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246,
     118                 :         245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232,
     119                 :         231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218,
     120                 :         472, 471, 470, 441, 440, 439, 438, 437, 436, 435, 448, 447, 446, 445,
     121                 :         444, 443, 442, 455, 454, 453, 452, 451, 450, 449, 462, 461, 460, 459,
     122                 :         458, 457, 456, 469, 468, 467, 466, 465, 464, 463, 479, 478, 477, 476,
     123                 :         475, 474, 473, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 483,
     124                 :         482, 481, 480, 496, 497, 495, 499, 500, 498, 494, 503, 504, 502, 506,
     125                 :         507, 505, 501, 510, 511, 509, 513, 514, 512, 508, 517, 518, 516, 520,
     126                 :         521, 519, 515, 524, 525, 523, 527, 528, 526, 522, 531, 532, 530, 534,
     127                 :         535, 533, 529, 538, 539, 537, 541, 542, 540, 536, 545, 546, 544, 548,
     128                 :         549, 547, 543, 552, 553, 551, 555, 556, 554, 550, 559, 560, 558, 562,
     129                 :         563, 561, 557, 566, 567, 565, 569, 570, 568, 564, 573, 574, 572, 576,
     130                 :         577, 575, 571, 580, 581, 579, 583, 584, 582, 578, 587, 588, 586, 590,
     131                 :         591, 589, 585, 594, 595, 593, 597, 598, 596, 592, 601, 602, 600, 604,
     132                 :         605, 603, 599, 608, 609, 607, 611, 612, 610, 606, 615, 616, 614, 618,
     133                 :         619, 617, 613, 622, 623, 621, 625, 626, 624, 620, 629, 630, 628, 632,
     134                 :         633, 631, 627, 640, 639, 638, 637, 636, 635, 634, 647, 646, 645, 644,
     135                 :         643, 642, 641, 654, 653, 652, 651, 650, 649, 648, 661, 660, 659, 658,
     136                 :         657, 656, 655, 668, 667, 666, 665, 664, 663, 662, 675, 674, 673, 672,
     137                 :         671, 670, 669, 682, 681, 680, 679, 678, 677, 676, 689, 688, 687, 686,
     138                 :         685, 684, 683, 696, 695, 694, 693, 692, 691, 690, 703, 702, 701, 700,
     139                 :         699, 698, 697, 773, 772, 771, 770, 769, 768, 767, 766, 765, 764, 763,
     140                 :         762, 761, 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, 749,
     141                 :         748, 747, 746, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735,
     142                 :         734, 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721,
     143                 :         720, 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707,
     144                 :         706, 705, 704, 913, 912, 911, 910, 909, 908, 907, 906, 905, 904, 903,
     145                 :         902, 901, 900, 899, 898, 897, 896, 895, 894, 893, 892, 891, 890, 889,
     146                 :         888, 887, 886, 885, 884, 883, 882, 881, 880, 879, 878, 877, 876, 875,
     147                 :         874, 873, 872, 871, 870, 869, 868, 867, 866, 865, 864, 863, 862, 861,
     148                 :         860, 859, 858, 857, 856, 855, 854, 853, 852, 851, 850, 849, 848, 847,
     149                 :         846, 845, 844, 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, 833,
     150                 :         832, 831, 830, 829, 828, 827, 826, 825, 824, 823, 822, 821, 820, 819,
     151                 :         818, 817, 816, 815, 814, 813, 812, 811, 810, 809, 808, 807, 806, 805,
     152                 :         804, 803, 802, 801, 800, 799, 798, 797, 796, 795, 794, 793, 792, 791,
     153                 :         790, 789, 788, 787, 786, 785, 784, 783, 782, 781, 780, 779, 778, 777,
     154                 :         776, 775, 774 };
     155                 : 
     156                 : PRInt32 sAggregateTestDoOrderArr[] = {
     157                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
     158                 :          15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
     159                 :          29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
     160                 :          43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
     161                 :          57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
     162                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
     163                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
     164                 :          99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
     165                 :         113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
     166                 :         127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
     167                 :         141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
     168                 :         155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
     169                 :         169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
     170                 :         183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
     171                 :         197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
     172                 :         211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
     173                 :         225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
     174                 :         239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
     175                 :         253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
     176                 :         267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
     177                 :         281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
     178                 :         295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
     179                 :         309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322,
     180                 :         323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
     181                 :         337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
     182                 :         351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
     183                 :         365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
     184                 :         379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392,
     185                 :         393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
     186                 :         407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,
     187                 :         421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
     188                 :         435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448,
     189                 :         449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462,
     190                 :         463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476,
     191                 :         477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490,
     192                 :         491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504,
     193                 :         505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518,
     194                 :         519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
     195                 :         533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546,
     196                 :         547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
     197                 :         561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
     198                 :         575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
     199                 :         589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602,
     200                 :         603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616,
     201                 :         617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630,
     202                 :         631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,
     203                 :         645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658,
     204                 :         659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672,
     205                 :         673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
     206                 :         687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700,
     207                 :         701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714,
     208                 :         715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728,
     209                 :         729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742,
     210                 :         743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756,
     211                 :         757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770,
     212                 :         771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784,
     213                 :         785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798,
     214                 :         799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812,
     215                 :         813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826,
     216                 :         827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840,
     217                 :         841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854,
     218                 :         855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868,
     219                 :         869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882,
     220                 :         883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896,
     221                 :         897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910,
     222                 :         911, 912, 913 };
     223                 : 
     224                 : PRInt32 sAggregateTestUndoOrderArr[] = {
     225                 :         287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274,
     226                 :         273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260,
     227                 :         434, 433, 432, 431, 430, 429, 428, 273, 272, 271, 270, 269, 268, 267,
     228                 :         266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253,
     229                 :         479, 478, 477, 476, 475, 493, 492, 491, 490, 489, 488, 487, 486, 485,
     230                 :         484, 483, 482, 481, 480, 485, 484, 483, 482, 481, 480, 773, 772, 771,
     231                 :         770, 769, 768, 767, 766, 765, 764, 763, 762, 761, 760, 759, 758, 757,
     232                 :         756, 755, 754, 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, 743,
     233                 :         742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730, 729,
     234                 :         728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715,
     235                 :         714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 913, 912, 911,
     236                 :         910, 909, 908, 907, 906, 905, 904, 903, 902, 901, 900, 899, 898, 897,
     237                 :         896, 895, 894, 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, 883,
     238                 :         882, 881, 880, 879, 878, 877, 876, 875, 874, 873, 872, 871, 870, 869,
     239                 :         868, 867, 866, 865, 864, 863, 862, 861, 860, 859, 858, 857, 856, 855,
     240                 :         854, 853, 852, 851, 850, 849, 848, 847, 846, 845, 844 };
     241                 : 
     242                 : PRInt32 sAggregateTestRedoOrderArr[] = {
     243                 :         260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
     244                 :         476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486 };
     245                 : 
     246                 : PRInt32 sSimpleBatchTestDestructorOrderArr[] = {
     247                 :          21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,
     248                 :          35,  36,  37,  38,  39,  40,  43,  42,  41,  64,  63,  62,  61,  60,
     249                 :          59,  58,  57,  56,  55,  54,  53,  52,  51,  50,  49,  48,  47,  46,
     250                 :          45,  44,  20,  19,  18,  17,  16,  15,  14,  13,  12,  11,  10,   9,
     251                 :           8,   7,   6,   5,   4,   3,   2,   1,  65,  67,  66,  68,  69,  70,
     252                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
     253                 :          85,  86,  87, 107, 106, 105, 104, 103, 102, 101, 100,  99,  98,  97,
     254                 :          96,  95,  94,  93,  92,  91,  90,  89,  88 };
     255                 : 
     256                 : PRInt32 sSimpleBatchTestDoOrderArr[] = {
     257                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
     258                 :          15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
     259                 :          29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
     260                 :          43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
     261                 :          57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
     262                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
     263                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
     264                 :          99, 100, 101, 102, 103, 104, 105, 106, 107 };
     265                 : 
     266                 : PRInt32 sSimpleBatchTestUndoOrderArr[] = {
     267                 :          43,  42,  41,  20,  19,  18,  17,  16,  15,  14,  13,  12,  11,  10,
     268                 :           9,   8,   7,   6,   5,   4,   3,   2,   1,  43,  42,  41,  63,  62,
     269                 :          61,  60,  59,  58,  57,  56,  55,  54,  53,  52,  51,  50,  49,  48,
     270                 :          47,  46,  45,  44,  65,  67,  66, 107, 106, 105, 104, 103, 102, 101,
     271                 :         100,  99,  98 };
     272                 : 
     273                 : PRInt32 sSimpleBatchTestRedoOrderArr[] = {
     274                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
     275                 :          15,  16,  17,  18,  19,  20,  41,  42,  43,  66 };
     276                 : 
     277                 : PRInt32 sAggregateBatchTestDestructorOrderArr[] = {
     278                 :         147, 146, 145, 144, 143, 142, 141, 154, 153, 152, 151, 150, 149, 148,
     279                 :         161, 160, 159, 158, 157, 156, 155, 168, 167, 166, 165, 164, 163, 162,
     280                 :         175, 174, 173, 172, 171, 170, 169, 182, 181, 180, 179, 178, 177, 176,
     281                 :         189, 188, 187, 186, 185, 184, 183, 196, 195, 194, 193, 192, 191, 190,
     282                 :         203, 202, 201, 200, 199, 198, 197, 210, 209, 208, 207, 206, 205, 204,
     283                 :         217, 216, 215, 214, 213, 212, 211, 224, 223, 222, 221, 220, 219, 218,
     284                 :         231, 230, 229, 228, 227, 226, 225, 238, 237, 236, 235, 234, 233, 232,
     285                 :         245, 244, 243, 242, 241, 240, 239, 252, 251, 250, 249, 248, 247, 246,
     286                 :         259, 258, 257, 256, 255, 254, 253, 266, 265, 264, 263, 262, 261, 260,
     287                 :         273, 272, 271, 270, 269, 268, 267, 280, 279, 278, 277, 276, 275, 274,
     288                 :         301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288,
     289                 :         287, 286, 285, 284, 283, 282, 281, 444, 443, 442, 441, 440, 439, 438,
     290                 :         437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424,
     291                 :         423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410,
     292                 :         409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 396,
     293                 :         395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 384, 383, 382,
     294                 :         381, 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368,
     295                 :         367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354,
     296                 :         353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340,
     297                 :         339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326,
     298                 :         325, 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312,
     299                 :         311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 140, 139, 138, 137,
     300                 :         136, 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123,
     301                 :         122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109,
     302                 :         108, 107, 106, 105, 104, 103, 102, 101, 100,  99,  98,  97,  96,  95,
     303                 :          94,  93,  92,  91,  90,  89,  88,  87,  86,  85,  84,  83,  82,  81,
     304                 :          80,  79,  78,  77,  76,  75,  74,  73,  72,  71,  70,  69,  68,  67,
     305                 :          66,  65,  64,  63,  62,  61,  60,  59,  58,  57,  56,  55,  54,  53,
     306                 :          52,  51,  50,  49,  48,  47,  46,  45,  44,  43,  42,  41,  40,  39,
     307                 :          38,  37,  36,  35,  34,  33,  32,  31,  30,  29,  28,  27,  26,  25,
     308                 :          24,  23,  22,  21,  20,  19,  18,  17,  16,  15,  14,  13,  12,  11,
     309                 :          10,   9,   8,   7,   6,   5,   4,   3,   2,   1, 451, 450, 449, 448,
     310                 :         447, 446, 445, 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, 455,
     311                 :         454, 453, 452, 468, 469, 467, 471, 472, 470, 466, 475, 476, 474, 478,
     312                 :         479, 477, 473, 482, 483, 481, 485, 486, 484, 480, 489, 490, 488, 492,
     313                 :         493, 491, 487, 496, 497, 495, 499, 500, 498, 494, 503, 504, 502, 506,
     314                 :         507, 505, 501, 510, 511, 509, 513, 514, 512, 508, 517, 518, 516, 520,
     315                 :         521, 519, 515, 524, 525, 523, 527, 528, 526, 522, 531, 532, 530, 534,
     316                 :         535, 533, 529, 538, 539, 537, 541, 542, 540, 536, 545, 546, 544, 548,
     317                 :         549, 547, 543, 552, 553, 551, 555, 556, 554, 550, 559, 560, 558, 562,
     318                 :         563, 561, 557, 566, 567, 565, 569, 570, 568, 564, 573, 574, 572, 576,
     319                 :         577, 575, 571, 580, 581, 579, 583, 584, 582, 578, 587, 588, 586, 590,
     320                 :         591, 589, 585, 594, 595, 593, 597, 598, 596, 592, 601, 602, 600, 604,
     321                 :         605, 603, 599, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735,
     322                 :         734, 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721,
     323                 :         720, 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707,
     324                 :         706, 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693,
     325                 :         692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679,
     326                 :         678, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, 665,
     327                 :         664, 663, 662, 661, 660, 659, 658, 657, 656, 655, 654, 653, 652, 651,
     328                 :         650, 649, 648, 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, 637,
     329                 :         636, 635, 634, 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, 623,
     330                 :         622, 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, 610, 609,
     331                 :         608, 607, 606 };
     332                 : 
     333                 : PRInt32 sAggregateBatchTestDoOrderArr[] = {
     334                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
     335                 :          15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
     336                 :          29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
     337                 :          43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
     338                 :          57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
     339                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
     340                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
     341                 :          99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
     342                 :         113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
     343                 :         127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
     344                 :         141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
     345                 :         155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
     346                 :         169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
     347                 :         183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
     348                 :         197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
     349                 :         211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
     350                 :         225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
     351                 :         239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
     352                 :         253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
     353                 :         267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
     354                 :         281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
     355                 :         295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
     356                 :         309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322,
     357                 :         323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
     358                 :         337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
     359                 :         351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
     360                 :         365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
     361                 :         379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392,
     362                 :         393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
     363                 :         407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,
     364                 :         421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
     365                 :         435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448,
     366                 :         449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462,
     367                 :         463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476,
     368                 :         477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490,
     369                 :         491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504,
     370                 :         505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518,
     371                 :         519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
     372                 :         533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546,
     373                 :         547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
     374                 :         561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
     375                 :         575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
     376                 :         589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602,
     377                 :         603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616,
     378                 :         617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630,
     379                 :         631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,
     380                 :         645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658,
     381                 :         659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672,
     382                 :         673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
     383                 :         687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700,
     384                 :         701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714,
     385                 :         715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728,
     386                 :         729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742,
     387                 :         743, 744, 745 };
     388                 : 
     389                 : PRInt32 sAggregateBatchTestUndoOrderArr[] = {
     390                 :         301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288,
     391                 :         287, 286, 285, 284, 283, 282, 281, 140, 139, 138, 137, 136, 135, 134,
     392                 :         133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120,
     393                 :         119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106,
     394                 :         105, 104, 103, 102, 101, 100,  99,  98,  97,  96,  95,  94,  93,  92,
     395                 :          91,  90,  89,  88,  87,  86,  85,  84,  83,  82,  81,  80,  79,  78,
     396                 :          77,  76,  75,  74,  73,  72,  71,  70,  69,  68,  67,  66,  65,  64,
     397                 :          63,  62,  61,  60,  59,  58,  57,  56,  55,  54,  53,  52,  51,  50,
     398                 :          49,  48,  47,  46,  45,  44,  43,  42,  41,  40,  39,  38,  37,  36,
     399                 :          35,  34,  33,  32,  31,  30,  29,  28,  27,  26,  25,  24,  23,  22,
     400                 :          21,  20,  19,  18,  17,  16,  15,  14,  13,  12,  11,  10,   9,   8,
     401                 :           7,   6,   5,   4,   3,   2,   1, 301, 300, 299, 298, 297, 296, 295,
     402                 :         294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281,
     403                 :         441, 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428,
     404                 :         427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414,
     405                 :         413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400,
     406                 :         399, 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386,
     407                 :         385, 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, 372,
     408                 :         371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358,
     409                 :         357, 356, 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, 344,
     410                 :         343, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330,
     411                 :         329, 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, 317, 316,
     412                 :         315, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302,
     413                 :         451, 450, 449, 448, 447, 465, 464, 463, 462, 461, 460, 459, 458, 457,
     414                 :         456, 455, 454, 453, 452, 457, 456, 455, 454, 453, 452, 745, 744, 743,
     415                 :         742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730, 729,
     416                 :         728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715,
     417                 :         714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 703, 702, 701,
     418                 :         700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687,
     419                 :         686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676 };
     420                 : 
     421                 : PRInt32 sAggregateBatchTestRedoOrderArr[] = {
     422                 :           1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
     423                 :          15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
     424                 :          29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
     425                 :          43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
     426                 :          57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
     427                 :          71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
     428                 :          85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
     429                 :          99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
     430                 :         113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
     431                 :         127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
     432                 :         281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
     433                 :         295, 296, 297, 298, 299, 300, 301, 448, 449, 450, 451, 452, 453, 454,
     434                 :         455, 456, 457, 458 };
     435                 : 
     436                 : #define TEST_TXMGR_IF_RELEASE(tx) if (tx) tx->Release(); // Release but don't clear pointer!
     437                 : 
     438                 : class TestTransaction : public nsITransaction
     439                 : {
     440                 : public:
     441                 : 
     442            4261 :   TestTransaction() {}
     443            8522 :   virtual ~TestTransaction() {}
     444                 : 
     445                 :   NS_DECL_ISUPPORTS
     446                 : };
     447                 : 
     448          102383 : NS_IMPL_ISUPPORTS1(TestTransaction, nsITransaction)
     449                 : 
     450                 : class SimpleTransaction : public TestTransaction
     451                 : {
     452                 : protected:
     453                 : 
     454                 : #define NONE_FLAG               0
     455                 : #define THROWS_DO_ERROR_FLAG    1
     456                 : #define THROWS_UNDO_ERROR_FLAG  2
     457                 : #define THROWS_REDO_ERROR_FLAG  4
     458                 : #define MERGE_FLAG              8
     459                 : #define TRANSIENT_FLAG         16
     460                 : #define BATCH_FLAG             32
     461                 : #define ALL_ERROR_FLAGS        (THROWS_DO_ERROR_FLAG|THROWS_UNDO_ERROR_FLAG|THROWS_REDO_ERROR_FLAG)
     462                 : 
     463                 :   PRInt32 mVal;
     464                 :   PRInt32 mFlags;
     465                 : 
     466                 : public:
     467                 : 
     468            4261 :   SimpleTransaction(PRInt32 aFlags=NONE_FLAG)
     469            4261 :                     : mVal(++sConstructorCount), mFlags(aFlags)
     470            4261 :   {}
     471                 : 
     472            4554 :   virtual ~SimpleTransaction()
     473            8522 :   {
     474                 :     //
     475                 :     // Make sure transactions are being destroyed in the order we expect!
     476                 :     // Notice that we don't check to see if we go past the end of the array.
     477                 :     // This is done on purpose since we want to crash if the order array is out
     478                 :     // of date.
     479                 :     //
     480            4261 :     if (sDestructorOrderArr && mVal != sDestructorOrderArr[sDestructorCount]) {
     481                 :       printf("ERROR: ~SimpleTransaction expected %d got %d.\n",
     482               0 :              mVal, sDestructorOrderArr[sDestructorCount]);
     483               0 :       exit(NS_ERROR_FAILURE);
     484                 :     }
     485                 : 
     486            4261 :     ++sDestructorCount;
     487                 : 
     488                 : #ifdef ENABLE_DEBUG_PRINTFS
     489                 :     printf("\n~SimpleTransaction: %d - 0x%.8x\n", mVal, (PRInt32)this);
     490                 : #endif // ENABLE_DEBUG_PRINTFS
     491                 : 
     492            4261 :     mVal = -1;
     493            9108 :   }
     494                 : 
     495            4261 :   NS_IMETHOD DoTransaction()
     496                 :   {
     497                 :     //
     498                 :     // Make sure DoTransaction() is called in the order we expect!
     499                 :     // Notice that we don't check to see if we go past the end of the array.
     500                 :     // This is done on purpose since we want to crash if the order array is out
     501                 :     // of date.
     502                 :     //
     503            4261 :     if (sDoOrderArr && mVal != sDoOrderArr[sDoCount]) {
     504                 :       printf("ERROR: DoTransaction expected %d got %d.\n",
     505               0 :              mVal, sDoOrderArr[sDoCount]);
     506               0 :       exit(NS_ERROR_FAILURE);
     507                 :     }
     508                 : 
     509            4261 :     ++sDoCount;
     510                 : 
     511                 : #ifdef ENABLE_DEBUG_PRINTFS
     512                 :     printf("\nSimpleTransaction.DoTransaction: %d - 0x%.8x\n", mVal, (PRInt32)this);
     513                 : #endif // ENABLE_DEBUG_PRINTFS
     514                 : 
     515            4261 :     return (mFlags & THROWS_DO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
     516                 :   }
     517                 : 
     518            5458 :   NS_IMETHOD UndoTransaction()
     519                 :   {
     520                 :     //
     521                 :     // Make sure UndoTransaction() is called in the order we expect!
     522                 :     // Notice that we don't check to see if we go past the end of the array.
     523                 :     // This is done on purpose since we want to crash if the order array is out
     524                 :     // of date.
     525                 :     //
     526            5458 :     if (sUndoOrderArr && mVal != sUndoOrderArr[sUndoCount]) {
     527                 :       printf("ERROR: UndoTransaction expected %d got %d.\n",
     528               0 :              mVal, sUndoOrderArr[sUndoCount]);
     529               0 :       exit(NS_ERROR_FAILURE);
     530                 :     }
     531                 : 
     532            5458 :     ++sUndoCount;
     533                 : 
     534                 : #ifdef ENABLE_DEBUG_PRINTFS
     535                 :     printf("\nSimpleTransaction.Undo: %d - 0x%.8x\n", mVal, (PRInt32)this);
     536                 : #endif // ENABLE_DEBUG_PRINTFS
     537                 : 
     538            5458 :     return (mFlags & THROWS_UNDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
     539                 :   }
     540                 : 
     541            2589 :   NS_IMETHOD RedoTransaction()
     542                 :   {
     543                 :     //
     544                 :     // Make sure RedoTransaction() is called in the order we expect!
     545                 :     // Notice that we don't check to see if we go past the end of the array.
     546                 :     // This is done on purpose since we want to crash if the order array is out
     547                 :     // of date.
     548                 :     //
     549            2589 :     if (sRedoOrderArr && mVal != sRedoOrderArr[sRedoCount]) {
     550                 :       printf("ERROR: RedoTransaction expected %d got %d.\n",
     551               0 :              mVal, sRedoOrderArr[sRedoCount]);
     552               0 :       exit(NS_ERROR_FAILURE);
     553                 :     }
     554                 : 
     555            2589 :     ++sRedoCount;
     556                 : 
     557                 : #ifdef ENABLE_DEBUG_PRINTFS
     558                 :     printf("\nSimpleTransaction.Redo: %d - 0x%.8x\n", mVal, (PRInt32)this);
     559                 : #endif // ENABLE_DEBUG_PRINTFS
     560                 : 
     561            2589 :     return (mFlags & THROWS_REDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
     562                 :   }
     563                 : 
     564            4253 :   NS_IMETHOD GetIsTransient(bool *aIsTransient)
     565                 :   {
     566            4253 :     if (aIsTransient)
     567            4253 :       *aIsTransient = (mFlags & TRANSIENT_FLAG) ? true : false;
     568                 : 
     569            4253 :     return NS_OK;
     570                 :   }
     571                 : 
     572             305 :   NS_IMETHOD Merge(nsITransaction *aTransaction, bool *aDidMerge)
     573                 :   {
     574             305 :     if (aDidMerge)
     575             305 :       *aDidMerge = (mFlags & MERGE_FLAG) ? true : false;
     576                 : 
     577             305 :     return NS_OK;
     578                 :   }
     579                 : };
     580                 : 
     581                 : class AggregateTransaction : public SimpleTransaction
     582                 : {
     583                 : private:
     584                 : 
     585            3620 :   AggregateTransaction(nsITransactionManager *aTXMgr, PRInt32 aLevel,
     586                 :                        PRInt32 aNumber, PRInt32 aMaxLevel,
     587                 :                        PRInt32 aNumChildrenPerNode,
     588                 :                        PRInt32 aFlags)
     589            3620 :   {
     590            3620 :     mLevel              = aLevel;
     591            3620 :     mNumber             = aNumber;
     592            3620 :     mTXMgr              = aTXMgr;
     593            3620 :     mFlags              = aFlags & (~ALL_ERROR_FLAGS);
     594            3620 :     mErrorFlags         = aFlags & ALL_ERROR_FLAGS;
     595            3620 :     mTXMgr              = aTXMgr;
     596            3620 :     mMaxLevel           = aMaxLevel;
     597            3620 :     mNumChildrenPerNode = aNumChildrenPerNode;
     598            3620 :   }
     599                 : 
     600                 :   nsITransactionManager *mTXMgr;
     601                 : 
     602                 :   PRInt32 mLevel;
     603                 :   PRInt32 mNumber;
     604                 :   PRInt32 mErrorFlags;
     605                 : 
     606                 :   PRInt32 mMaxLevel;
     607                 :   PRInt32 mNumChildrenPerNode;
     608                 : 
     609                 : public:
     610                 : 
     611             348 :   AggregateTransaction(nsITransactionManager *aTXMgr,
     612                 :                        PRInt32 aMaxLevel, PRInt32 aNumChildrenPerNode,
     613                 :                        PRInt32 aFlags=NONE_FLAG)
     614             348 :   {
     615             348 :     mLevel              = 1;
     616             348 :     mNumber             = 1;
     617             348 :     mFlags              = aFlags & (~ALL_ERROR_FLAGS);
     618             348 :     mErrorFlags         = aFlags & ALL_ERROR_FLAGS;
     619             348 :     mTXMgr              = aTXMgr;
     620             348 :     mMaxLevel           = aMaxLevel;
     621             348 :     mNumChildrenPerNode = aNumChildrenPerNode;
     622             348 :   }
     623                 : 
     624            7936 :   virtual ~AggregateTransaction()
     625            3968 :   {
     626                 :     // printf("~AggregateTransaction(0x%.8x) - %3d (%3d)\n", this, mLevel, mVal);
     627           15872 :   }
     628                 : 
     629            3968 :   NS_IMETHOD DoTransaction()
     630                 :   {
     631            3968 :     if (mLevel >= mMaxLevel) {
     632                 :       // Only leaf nodes can throw errors!
     633            2706 :       mFlags |= mErrorFlags;
     634                 :     }
     635                 : 
     636            3968 :     nsresult result = SimpleTransaction::DoTransaction();
     637                 : 
     638            3968 :     if (NS_FAILED(result)) {
     639                 :       // printf("ERROR: QueryInterface() failed for transaction level %d. (%d)\n",
     640                 :       //       mLevel, result);
     641               2 :       return result;
     642                 :     }
     643                 : 
     644            3966 :     if (mLevel >= mMaxLevel)
     645            2704 :       return NS_OK;
     646                 : 
     647            1262 :     if (mFlags & BATCH_FLAG) {
     648             595 :       result = mTXMgr->BeginBatch();
     649             595 :       if (NS_FAILED(result)) {
     650               0 :         return result;
     651                 :       }
     652                 :     }
     653                 : 
     654            1262 :     PRInt32 cLevel = mLevel + 1;
     655                 : 
     656            4878 :     for (int i = 1; i <= mNumChildrenPerNode; i++) {
     657            3620 :       PRInt32 flags = mErrorFlags & THROWS_DO_ERROR_FLAG;
     658                 : 
     659            3620 :       if ((mErrorFlags & THROWS_REDO_ERROR_FLAG) && i == mNumChildrenPerNode) {
     660                 :         // Make the rightmost leaf transaction throw the error!
     661               4 :         flags = THROWS_REDO_ERROR_FLAG;
     662               4 :         mErrorFlags = mErrorFlags & (~THROWS_REDO_ERROR_FLAG);
     663                 :       }
     664            3616 :       else if ((mErrorFlags & THROWS_UNDO_ERROR_FLAG)
     665                 :                && i == 1) {
     666                 :         // Make the leftmost leaf transaction throw the error!
     667               4 :         flags = THROWS_UNDO_ERROR_FLAG;
     668               4 :         mErrorFlags = mErrorFlags & (~THROWS_UNDO_ERROR_FLAG);
     669                 :       }
     670                 : 
     671            3620 :       flags |= mFlags & BATCH_FLAG;
     672                 : 
     673                 :       AggregateTransaction *tximpl =
     674                 :               new AggregateTransaction(mTXMgr, cLevel, i, mMaxLevel,
     675            3620 :                                        mNumChildrenPerNode, flags);
     676                 : 
     677            3620 :       if (!tximpl) {
     678                 :         printf("ERROR: Failed to allocate AggregateTransaction %d, level %d. (%d)\n",
     679               0 :                i, mLevel, result);
     680                 : 
     681               0 :         if (mFlags & BATCH_FLAG)
     682               0 :           mTXMgr->EndBatch();
     683                 : 
     684               0 :         return NS_ERROR_OUT_OF_MEMORY;
     685                 :       }
     686                 : 
     687            3620 :       nsITransaction *tx = 0;
     688            3620 :       result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
     689            3620 :       if (NS_FAILED(result)) {
     690                 :         printf("ERROR: QueryInterface() failed for transaction %d, level %d. (%d)\n",
     691               0 :                i, mLevel, result);
     692                 : 
     693               0 :         if (mFlags & BATCH_FLAG)
     694               0 :           mTXMgr->EndBatch();
     695                 : 
     696               0 :         return result;
     697                 :       }
     698                 : 
     699            3620 :       result = mTXMgr->DoTransaction(tx);
     700                 : 
     701            3620 :       if (NS_FAILED(result)) {
     702                 :         // printf("ERROR: Failed to execute transaction %d, level %d. (%d)\n",
     703                 :         //        i, mLevel, result);
     704               4 :         tx->Release();
     705                 : 
     706               4 :         if (mFlags & BATCH_FLAG)
     707               2 :           mTXMgr->EndBatch();
     708                 : 
     709               4 :         return result;
     710                 :       }
     711                 : 
     712            3616 :       tx->Release();
     713                 :     }
     714                 : 
     715            1258 :     if (mFlags & BATCH_FLAG)
     716             593 :       mTXMgr->EndBatch();
     717                 : 
     718            1258 :     return result;
     719                 :   }
     720                 : };
     721                 : 
     722                 : class TestTransactionFactory
     723               7 : {
     724                 : public:
     725                 :   virtual TestTransaction *create(nsITransactionManager *txmgr, PRInt32 flags) = 0;
     726                 : };
     727                 : 
     728                 : class SimpleTransactionFactory : public TestTransactionFactory
     729               3 : {
     730                 : public:
     731                 : 
     732             293 :   TestTransaction *create(nsITransactionManager *txmgr, PRInt32 flags)
     733                 :   {
     734             293 :     return (TestTransaction *)new SimpleTransaction(flags);
     735                 :   }
     736                 : };
     737                 : 
     738                 : class AggregateTransactionFactory : public TestTransactionFactory
     739                 : {
     740                 : private:
     741                 : 
     742                 :   PRInt32 mMaxLevel;
     743                 :   PRInt32 mNumChildrenPerNode;
     744                 :   PRInt32 mFixedFlags;
     745                 : 
     746                 : public:
     747                 : 
     748               4 :   AggregateTransactionFactory(PRInt32 aMaxLevel, PRInt32 aNumChildrenPerNode,
     749                 :                               PRInt32 aFixedFlags=NONE_FLAG)
     750                 :       : mMaxLevel(aMaxLevel), mNumChildrenPerNode(aNumChildrenPerNode),
     751               4 :         mFixedFlags(aFixedFlags)
     752                 :   {
     753               4 :   }
     754                 : 
     755             348 :   virtual TestTransaction *create(nsITransactionManager *txmgr, PRInt32 flags)
     756                 :   {
     757                 :     return (TestTransaction *)new AggregateTransaction(txmgr, mMaxLevel,
     758                 :                                                        mNumChildrenPerNode,
     759             348 :                                                        flags | mFixedFlags);
     760                 :   }
     761                 : };
     762                 : 
     763                 : void
     764               7 : reset_globals()
     765                 : {
     766               7 :   sConstructorCount   = 0;
     767                 : 
     768               7 :   sDestructorCount    = 0;
     769               7 :   sDestructorOrderArr = 0;
     770                 : 
     771               7 :   sDoCount            = 0;
     772               7 :   sDoOrderArr         = 0;
     773                 : 
     774               7 :   sUndoCount          = 0;
     775               7 :   sUndoOrderArr       = 0;
     776                 : 
     777               7 :   sRedoCount          = 0;
     778               7 :   sRedoOrderArr       = 0;
     779               7 : }
     780                 : 
     781                 : /**
     782                 :  * Test behaviors in non-batch mode.
     783                 :  **/
     784                 : nsresult
     785               2 : quick_test(TestTransactionFactory *factory)
     786                 : {
     787                 :   nsresult result;
     788                 : 
     789                 :   /*******************************************************************
     790                 :    *
     791                 :    * Create a transaction manager implementation:
     792                 :    *
     793                 :    *******************************************************************/
     794                 : 
     795                 :   nsCOMPtr<nsITransactionManager> mgr =
     796               4 :     do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
     797               2 :   if (NS_FAILED(result) || !mgr) {
     798               0 :     printf("ERROR: Failed to create Transaction Manager instance.\n");
     799               0 :     return NS_ERROR_OUT_OF_MEMORY;
     800                 :   }
     801                 : 
     802               2 :   passed("Create transaction manager instance");
     803                 : 
     804                 :   /*******************************************************************
     805                 :    *
     806                 :    * Call DoTransaction() with a null transaction:
     807                 :    *
     808                 :    *******************************************************************/
     809                 : 
     810               2 :   result = mgr->DoTransaction(0);
     811                 : 
     812               2 :   if (result != NS_ERROR_NULL_POINTER) {
     813               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
     814               0 :     return result;
     815                 :   }
     816                 : 
     817               2 :   passed("Call DoTransaction() with null transaction");
     818                 : 
     819                 :   /*******************************************************************
     820                 :    *
     821                 :    * Call UndoTransaction() with an empty undo stack:
     822                 :    *
     823                 :    *******************************************************************/
     824                 : 
     825               2 :   result = mgr->UndoTransaction();
     826                 : 
     827               2 :   if (NS_FAILED(result)) {
     828               0 :     printf("ERROR: Undo on empty undo stack failed. (%d)\n", result);
     829               0 :     return result;
     830                 :   }
     831                 : 
     832               2 :   passed("Call UndoTransaction() with empty undo stack");
     833                 : 
     834                 :   /*******************************************************************
     835                 :    *
     836                 :    * Call RedoTransaction() with an empty redo stack:
     837                 :    *
     838                 :    *******************************************************************/
     839                 : 
     840               2 :   result = mgr->RedoTransaction();
     841                 : 
     842               2 :   if (NS_FAILED(result)) {
     843               0 :     printf("ERROR: Redo on empty redo stack failed. (%d)\n", result);
     844               0 :     return result;
     845                 :   }
     846                 : 
     847               2 :   passed("Call RedoTransaction() with empty redo stack");
     848                 : 
     849                 :   /*******************************************************************
     850                 :    *
     851                 :    * Call SetMaxTransactionCount(-1) with empty undo and redo stacks:
     852                 :    *
     853                 :    *******************************************************************/
     854                 : 
     855               2 :   result = mgr->SetMaxTransactionCount(-1);
     856                 : 
     857               2 :   if (NS_FAILED(result)) {
     858               0 :     printf("ERROR: SetMaxTransactionCount(-1) failed. (%d)\n", result);
     859               0 :     return result;
     860                 :   }
     861                 : 
     862               2 :   passed("Call SetMaxTransactionCount(-1) with empty undo and redo stacks");
     863                 : 
     864                 :   /*******************************************************************
     865                 :    *
     866                 :    * Call SetMaxTransactionCount(0) with empty undo and redo stacks:
     867                 :    *
     868                 :    *******************************************************************/
     869                 : 
     870               2 :   result = mgr->SetMaxTransactionCount(0);
     871                 : 
     872               2 :   if (NS_FAILED(result)) {
     873               0 :     printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
     874               0 :     return result;
     875                 :   }
     876                 : 
     877               2 :   passed("Call SetMaxTransactionCount(0) with empty undo and redo stacks");
     878                 : 
     879                 :   /*******************************************************************
     880                 :    *
     881                 :    * Call SetMaxTransactionCount(10) with empty undo and redo stacks:
     882                 :    *
     883                 :    *******************************************************************/
     884                 : 
     885               2 :   result = mgr->SetMaxTransactionCount(10);
     886                 : 
     887               2 :   if (NS_FAILED(result)) {
     888               0 :     printf("ERROR: SetMaxTransactionCount(10) failed. (%d)\n", result);
     889               0 :     return result;
     890                 :   }
     891                 : 
     892               2 :   passed("Call SetMaxTransactionCount(10) with empty undo and redo stacks");
     893                 : 
     894                 :   /*******************************************************************
     895                 :    *
     896                 :    * Call Clear() with empty undo and redo stacks:
     897                 :    *
     898                 :    *******************************************************************/
     899                 : 
     900               2 :   result = mgr->Clear();
     901               2 :   if (NS_FAILED(result)) {
     902               0 :     printf("ERROR: Clear on empty undo and redo stack failed. (%d)\n", result);
     903               0 :     return result;
     904                 :   }
     905                 : 
     906               2 :   passed("Call Clear() with empty undo and redo stack");
     907                 : 
     908                 :   PRInt32 numitems;
     909                 : 
     910                 :   /*******************************************************************
     911                 :    *
     912                 :    * Call GetNumberOfUndoItems() with an empty undo stack:
     913                 :    *
     914                 :    *******************************************************************/
     915                 : 
     916               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
     917                 : 
     918               2 :   if (NS_FAILED(result)) {
     919                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
     920               0 :            result);
     921               0 :     return result;
     922                 :   }
     923                 : 
     924               2 :   if (numitems != 0) {
     925                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
     926               0 :            numitems, result);
     927               0 :     return NS_ERROR_FAILURE;
     928                 :   }
     929                 : 
     930               2 :   passed("Call GetNumberOfUndoItems() with empty undo stack");
     931                 : 
     932                 :   /*******************************************************************
     933                 :    *
     934                 :    * Call GetNumberOfRedoItems() with an empty redo stack:
     935                 :    *
     936                 :    *******************************************************************/
     937                 : 
     938               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
     939                 : 
     940               2 :   if (NS_FAILED(result)) {
     941                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
     942               0 :            result);
     943               0 :     return result;
     944                 :   }
     945                 : 
     946               2 :   if (numitems != 0) {
     947                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
     948               0 :            numitems, result);
     949               0 :     return NS_ERROR_FAILURE;
     950                 :   }
     951                 : 
     952               2 :   passed("Call GetNumberOfRedoItems() with empty redo stack");
     953                 : 
     954                 :   nsITransaction *tx;
     955                 : 
     956                 :   /*******************************************************************
     957                 :    *
     958                 :    * Call PeekUndoStack() with an empty undo stack:
     959                 :    *
     960                 :    *******************************************************************/
     961                 : 
     962               2 :   tx = 0;
     963               2 :   result = mgr->PeekUndoStack(&tx);
     964                 : 
     965               2 :   TEST_TXMGR_IF_RELEASE(tx); // Don't hold onto any references!
     966                 : 
     967               2 :   if (NS_FAILED(result)) {
     968               0 :     printf("ERROR: PeekUndoStack() on empty undo stack failed. (%d)\n", result);
     969               0 :     return result;
     970                 :   }
     971                 : 
     972               2 :   if (tx != 0) {
     973               0 :     printf("ERROR: PeekUndoStack() on empty undo stack failed. (%d)\n", result);
     974               0 :     return NS_ERROR_FAILURE;
     975                 :   }
     976                 : 
     977               2 :   passed("Call PeekUndoStack() with empty undo stack");
     978                 : 
     979                 :   /*******************************************************************
     980                 :    *
     981                 :    * Call PeekRedoStack() with an empty undo stack:
     982                 :    *
     983                 :    *******************************************************************/
     984                 : 
     985               2 :   tx = 0;
     986               2 :   result = mgr->PeekRedoStack(&tx);
     987                 : 
     988               2 :   TEST_TXMGR_IF_RELEASE(tx); // Don't hold onto any references!
     989                 : 
     990               2 :   if (NS_FAILED(result)) {
     991               0 :     printf("ERROR: PeekRedoStack() on empty redo stack failed. (%d)\n", result);
     992               0 :     return result;
     993                 :   }
     994                 : 
     995               2 :   if (tx != 0) {
     996               0 :     printf("ERROR: PeekRedoStack() on empty redo stack failed. (%d)\n", result);
     997               0 :     return NS_ERROR_FAILURE;
     998                 :   }
     999                 : 
    1000               2 :   passed("Call PeekRedoStack() with empty undo stack");
    1001                 : 
    1002                 :   /*******************************************************************
    1003                 :    *
    1004                 :    * Call AddListener() with a null listener pointer:
    1005                 :    *
    1006                 :    *******************************************************************/
    1007                 : 
    1008               2 :   result = mgr->AddListener(0);
    1009                 : 
    1010               2 :   if (result != NS_ERROR_NULL_POINTER) {
    1011               0 :     printf("ERROR: AddListener() returned unexpected error. (%d)\n", result);
    1012               0 :     return result;
    1013                 :   }
    1014                 : 
    1015               2 :   passed("Call AddListener() with null listener");
    1016                 : 
    1017                 :   /*******************************************************************
    1018                 :    *
    1019                 :    * Call RemoveListener() with a null listener pointer:
    1020                 :    *
    1021                 :    *******************************************************************/
    1022                 : 
    1023               2 :   result = mgr->RemoveListener(0);
    1024                 : 
    1025               2 :   if (result != NS_ERROR_NULL_POINTER) {
    1026               0 :     printf("ERROR: RemoveListener() returned unexpected error. (%d)\n", result);
    1027               0 :     return result;
    1028                 :   }
    1029                 : 
    1030               2 :   passed("Call RemoveListener() with null listener");
    1031                 : 
    1032                 :   PRInt32 i;
    1033                 :   TestTransaction *tximpl;
    1034                 :   nsITransaction *u1, *u2;
    1035                 :   nsITransaction *r1, *r2;
    1036                 : 
    1037                 :   /*******************************************************************
    1038                 :    *
    1039                 :    * Test coalescing by executing a transaction that can merge any
    1040                 :    * command into itself. Then execute 20 transaction. Afterwards,
    1041                 :    * we should still have the first transaction sitting on the undo
    1042                 :    * stack. Then clear the undo and redo stacks.
    1043                 :    *
    1044                 :    *******************************************************************/
    1045                 : 
    1046               2 :   result = mgr->SetMaxTransactionCount(10);
    1047                 : 
    1048               2 :   if (NS_FAILED(result)) {
    1049               0 :     printf("ERROR: SetMaxTransactionCount(10) failed. (%d)\n", result);
    1050               0 :     return result;
    1051                 :   }
    1052                 : 
    1053                 : 
    1054               2 :   tximpl = factory->create(mgr, MERGE_FLAG);
    1055                 : 
    1056               2 :   if (!tximpl) {
    1057               0 :     printf("ERROR: Failed to allocate initial transaction.\n");
    1058               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1059                 :   }
    1060                 : 
    1061               2 :   tx = 0;
    1062                 : 
    1063               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1064                 : 
    1065               2 :   if (NS_FAILED(result)) {
    1066                 :     printf("ERROR: QueryInterface() failed for initial transaction. (%d)\n",
    1067               0 :            result);
    1068               0 :     return result;
    1069                 :   }
    1070                 : 
    1071               2 :   result = mgr->DoTransaction(tx);
    1072                 : 
    1073               2 :   if (NS_FAILED(result)) {
    1074               0 :     printf("ERROR: Failed to execute initial transaction. (%d)\n", result);
    1075               0 :     return result;
    1076                 :   }
    1077                 : 
    1078               2 :   tx->Release();
    1079                 : 
    1080               2 :   u1 = u2 = r1 = r2 = 0;
    1081                 : 
    1082               2 :   result = mgr->PeekUndoStack(&u1);
    1083                 : 
    1084               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    1085                 : 
    1086               2 :   if (NS_FAILED(result)) {
    1087               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    1088               0 :     return result;
    1089                 :   }
    1090                 : 
    1091               2 :   if (u1 != tx) {
    1092               0 :     printf("ERROR: Top of undo stack is different!. (%d)\n", result);
    1093               0 :     return NS_ERROR_FAILURE;
    1094                 :   }
    1095                 : 
    1096               2 :   result = mgr->PeekRedoStack(&r1);
    1097                 : 
    1098               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    1099                 : 
    1100               2 :   if (NS_FAILED(result)) {
    1101               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    1102               0 :     return result;
    1103                 :   }
    1104                 : 
    1105              42 :   for (i = 1; i <= 20; i++) {
    1106              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    1107                 : 
    1108              40 :     if (!tximpl) {
    1109               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    1110               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1111                 :     }
    1112                 : 
    1113              40 :     tx = 0;
    1114              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1115              40 :     if (NS_FAILED(result)) {
    1116                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    1117               0 :              i, result);
    1118               0 :       return result;
    1119                 :     }
    1120                 : 
    1121              40 :     result = mgr->DoTransaction(tx);
    1122              40 :     if (NS_FAILED(result)) {
    1123               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    1124               0 :       return result;
    1125                 :     }
    1126                 : 
    1127              40 :     tx->Release();
    1128                 :   }
    1129                 : 
    1130               2 :   result = mgr->PeekUndoStack(&u2);
    1131                 : 
    1132               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    1133                 : 
    1134               2 :   if (NS_FAILED(result)) {
    1135               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    1136               0 :     return result;
    1137                 :   }
    1138                 : 
    1139               2 :   if (u1 != u2) {
    1140               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    1141               0 :     return NS_ERROR_FAILURE;
    1142                 :   }
    1143                 : 
    1144               2 :   result = mgr->PeekRedoStack(&r2);
    1145                 : 
    1146               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    1147                 : 
    1148               2 :   if (NS_FAILED(result)) {
    1149               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    1150               0 :     return result;
    1151                 :   }
    1152                 : 
    1153               2 :   if (r1 != r2) {
    1154               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    1155               0 :     return NS_ERROR_FAILURE;
    1156                 :   }
    1157                 : 
    1158               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1159                 : 
    1160               2 :   if (NS_FAILED(result)) {
    1161                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    1162               0 :            result);
    1163               0 :     return result;
    1164                 :   }
    1165                 : 
    1166               2 :   if (numitems != 1) {
    1167                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    1168               0 :            numitems, result);
    1169               0 :     return NS_ERROR_FAILURE;
    1170                 :   }
    1171                 : 
    1172               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1173                 : 
    1174               2 :   if (NS_FAILED(result)) {
    1175                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    1176               0 :            result);
    1177               0 :     return result;
    1178                 :   }
    1179                 : 
    1180               2 :   if (numitems != 0) {
    1181                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1182               0 :            numitems, result);
    1183               0 :     return NS_ERROR_FAILURE;
    1184                 :   }
    1185                 : 
    1186               2 :   result = mgr->Clear();
    1187               2 :   if (NS_FAILED(result)) {
    1188               0 :     printf("ERROR: Clear() failed. (%d)\n", result);
    1189               0 :     return result;
    1190                 :   }
    1191                 : 
    1192               2 :   passed("Test coalescing of transactions");
    1193                 : 
    1194                 :   /*******************************************************************
    1195                 :    *
    1196                 :    * Execute 20 transactions. Afterwards, we should have 10
    1197                 :    * transactions on the undo stack:
    1198                 :    *
    1199                 :    *******************************************************************/
    1200                 : 
    1201              42 :   for (i = 1; i <= 20; i++) {
    1202              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    1203                 : 
    1204              40 :     if (!tximpl) {
    1205               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    1206               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1207                 :     }
    1208                 : 
    1209              40 :     tx = 0;
    1210              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1211              40 :     if (NS_FAILED(result)) {
    1212                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    1213               0 :              i, result);
    1214               0 :       return result;
    1215                 :     }
    1216                 : 
    1217              40 :     result = mgr->DoTransaction(tx);
    1218              40 :     if (NS_FAILED(result)) {
    1219               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    1220               0 :       return result;
    1221                 :     }
    1222                 : 
    1223              40 :     tx->Release();
    1224                 :   }
    1225                 : 
    1226               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1227                 : 
    1228               2 :   if (NS_FAILED(result)) {
    1229                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
    1230               0 :            result);
    1231               0 :     return result;
    1232                 :   }
    1233                 : 
    1234               2 :   if (numitems != 10) {
    1235                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    1236               0 :            numitems, result);
    1237               0 :     return NS_ERROR_FAILURE;
    1238                 :   }
    1239                 : 
    1240               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1241                 : 
    1242               2 :   if (NS_FAILED(result)) {
    1243                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    1244               0 :            result);
    1245               0 :     return result;
    1246                 :   }
    1247                 : 
    1248               2 :   if (numitems != 0) {
    1249                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1250               0 :            numitems, result);
    1251               0 :     return NS_ERROR_FAILURE;
    1252                 :   }
    1253                 : 
    1254               2 :   passed("Execute 20 transactions");
    1255                 : 
    1256                 :   /*******************************************************************
    1257                 :    *
    1258                 :    * Execute 20 transient transactions. Afterwards, we should still
    1259                 :    * have the same 10 transactions on the undo stack:
    1260                 :    *
    1261                 :    *******************************************************************/
    1262                 : 
    1263               2 :   u1 = u2 = r1 = r2 = 0;
    1264                 : 
    1265               2 :   result = mgr->PeekUndoStack(&u1);
    1266                 : 
    1267               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    1268                 : 
    1269               2 :   if (NS_FAILED(result)) {
    1270               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    1271               0 :     return result;
    1272                 :   }
    1273                 : 
    1274               2 :   result = mgr->PeekRedoStack(&r1);
    1275                 : 
    1276               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    1277                 : 
    1278               2 :   if (NS_FAILED(result)) {
    1279               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    1280               0 :     return result;
    1281                 :   }
    1282                 : 
    1283              42 :   for (i = 1; i <= 20; i++) {
    1284              40 :     tximpl = factory->create(mgr, TRANSIENT_FLAG);
    1285                 : 
    1286              40 :     if (!tximpl) {
    1287               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    1288               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1289                 :     }
    1290                 : 
    1291              40 :     tx = 0;
    1292              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1293              40 :     if (NS_FAILED(result)) {
    1294                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    1295               0 :              i, result);
    1296               0 :       return result;
    1297                 :     }
    1298                 : 
    1299              40 :     result = mgr->DoTransaction(tx);
    1300              40 :     if (NS_FAILED(result)) {
    1301               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    1302               0 :       return result;
    1303                 :     }
    1304                 : 
    1305              40 :     tx->Release();
    1306                 :   }
    1307                 : 
    1308               2 :   result = mgr->PeekUndoStack(&u2);
    1309                 : 
    1310               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    1311                 : 
    1312               2 :   if (NS_FAILED(result)) {
    1313               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    1314               0 :     return result;
    1315                 :   }
    1316                 : 
    1317               2 :   if (u1 != u2) {
    1318               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    1319               0 :     return NS_ERROR_FAILURE;
    1320                 :   }
    1321                 : 
    1322               2 :   result = mgr->PeekRedoStack(&r2);
    1323                 : 
    1324               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    1325                 : 
    1326               2 :   if (NS_FAILED(result)) {
    1327               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    1328               0 :     return result;
    1329                 :   }
    1330                 : 
    1331               2 :   if (r1 != r2) {
    1332               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    1333               0 :     return NS_ERROR_FAILURE;
    1334                 :   }
    1335                 : 
    1336               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1337                 : 
    1338               2 :   if (NS_FAILED(result)) {
    1339                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
    1340               0 :            result);
    1341               0 :     return result;
    1342                 :   }
    1343                 : 
    1344               2 :   if (numitems != 10) {
    1345                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    1346               0 :            numitems, result);
    1347               0 :     return NS_ERROR_FAILURE;
    1348                 :   }
    1349                 : 
    1350               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1351                 : 
    1352               2 :   if (NS_FAILED(result)) {
    1353                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    1354               0 :            result);
    1355               0 :     return result;
    1356                 :   }
    1357                 : 
    1358               2 :   if (numitems != 0) {
    1359                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1360               0 :            numitems, result);
    1361               0 :     return NS_ERROR_FAILURE;
    1362                 :   }
    1363                 : 
    1364               2 :   passed("Execute 20 transient transactions");
    1365                 : 
    1366                 :   /*******************************************************************
    1367                 :    *
    1368                 :    * Undo 4 transactions. Afterwards, we should have 6 transactions
    1369                 :    * on the undo stack, and 4 on the redo stack:
    1370                 :    *
    1371                 :    *******************************************************************/
    1372                 : 
    1373              10 :   for (i = 1; i <= 4; i++) {
    1374               8 :     result = mgr->UndoTransaction();
    1375               8 :     if (NS_FAILED(result)) {
    1376               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    1377               0 :       return result;
    1378                 :     }
    1379                 :   }
    1380                 : 
    1381               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1382                 : 
    1383               2 :   if (NS_FAILED(result)) {
    1384                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
    1385               0 :            result);
    1386               0 :     return result;
    1387                 :   }
    1388                 : 
    1389               2 :   if (numitems != 6) {
    1390                 :     printf("ERROR: GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
    1391               0 :            numitems, result);
    1392               0 :     return NS_ERROR_FAILURE;
    1393                 :   }
    1394                 : 
    1395               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1396                 : 
    1397               2 :   if (NS_FAILED(result)) {
    1398                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 4 items failed. (%d)\n",
    1399               0 :            result);
    1400               0 :     return result;
    1401                 :   }
    1402                 : 
    1403               2 :   if (numitems != 4) {
    1404                 :     printf("ERROR: GetNumberOfRedoItems() expected 4 got %d. (%d)\n",
    1405               0 :            numitems, result);
    1406               0 :     return NS_ERROR_FAILURE;
    1407                 :   }
    1408                 : 
    1409               2 :   passed("Undo 4 transactions");
    1410                 : 
    1411                 :   /*******************************************************************
    1412                 :    *
    1413                 :    * Redo 2 transactions. Afterwards, we should have 8 transactions
    1414                 :    * on the undo stack, and 2 on the redo stack:
    1415                 :    *
    1416                 :    *******************************************************************/
    1417                 : 
    1418               6 :   for (i = 1; i <= 2; ++i) {
    1419               4 :     result = mgr->RedoTransaction();
    1420               4 :     if (NS_FAILED(result)) {
    1421               0 :       printf("ERROR: Failed to redo transaction %d. (%d)\n", i, result);
    1422               0 :       return result;
    1423                 :     }
    1424                 :   }
    1425                 : 
    1426               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1427                 : 
    1428               2 :   if (NS_FAILED(result)) {
    1429                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 8 items failed. (%d)\n",
    1430               0 :            result);
    1431               0 :     return result;
    1432                 :   }
    1433                 : 
    1434               2 :   if (numitems != 8) {
    1435                 :     printf("ERROR: GetNumberOfUndoItems() expected 8 got %d. (%d)\n",
    1436               0 :            numitems, result);
    1437               0 :     return NS_ERROR_FAILURE;
    1438                 :   }
    1439                 : 
    1440               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1441                 : 
    1442               2 :   if (NS_FAILED(result)) {
    1443                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
    1444               0 :            result);
    1445               0 :     return result;
    1446                 :   }
    1447                 : 
    1448               2 :   if (numitems != 2) {
    1449                 :     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
    1450               0 :            numitems, result);
    1451               0 :     return NS_ERROR_FAILURE;
    1452                 :   }
    1453                 : 
    1454               2 :   passed("Redo 2 transactions");
    1455                 : 
    1456                 :   /*******************************************************************
    1457                 :    *
    1458                 :    * Execute a new transaction. The redo stack should get pruned!
    1459                 :    *
    1460                 :    *******************************************************************/
    1461                 : 
    1462               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    1463                 : 
    1464               2 :   if (!tximpl) {
    1465               0 :     printf("ERROR: Failed to allocate transaction.\n");
    1466               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1467                 :   }
    1468                 : 
    1469               2 :   tx = 0;
    1470                 : 
    1471               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1472                 : 
    1473               2 :   if (NS_FAILED(result)) {
    1474               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    1475               0 :     return result;
    1476                 :   }
    1477                 : 
    1478               2 :   result = mgr->DoTransaction(tx);
    1479               2 :   if (NS_FAILED(result)) {
    1480               0 :     printf("ERROR: Failed to execute transaction. (%d)\n", result);
    1481               0 :     return result;
    1482                 :   }
    1483                 : 
    1484               2 :   tx->Release();
    1485                 : 
    1486               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1487                 : 
    1488               2 :   if (NS_FAILED(result)) {
    1489                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 9 items failed. (%d)\n",
    1490               0 :            result);
    1491               0 :     return result;
    1492                 :   }
    1493                 : 
    1494               2 :   if (numitems != 9) {
    1495                 :     printf("ERROR: GetNumberOfUndoItems() expected 9 got %d. (%d)\n",
    1496               0 :            numitems, result);
    1497               0 :     return NS_ERROR_FAILURE;
    1498                 :   }
    1499                 : 
    1500               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1501                 : 
    1502               2 :   if (NS_FAILED(result)) {
    1503                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    1504               0 :            result);
    1505               0 :     return result;
    1506                 :   }
    1507                 : 
    1508               2 :   if (numitems != 0) {
    1509                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1510               0 :            numitems, result);
    1511               0 :     return NS_ERROR_FAILURE;
    1512                 :   }
    1513                 : 
    1514               2 :   passed("Check if new transactions prune the redo stack");
    1515                 : 
    1516                 :   /*******************************************************************
    1517                 :    *
    1518                 :    * Undo 4 transactions then clear the undo and redo stacks.
    1519                 :    *
    1520                 :    *******************************************************************/
    1521                 : 
    1522              10 :   for (i = 1; i <= 4; ++i) {
    1523               8 :     result = mgr->UndoTransaction();
    1524               8 :     if (NS_FAILED(result)) {
    1525               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    1526               0 :       return result;
    1527                 :     }
    1528                 :   }
    1529                 : 
    1530               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1531                 : 
    1532               2 :   if (NS_FAILED(result)) {
    1533                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
    1534               0 :            result);
    1535               0 :     return result;
    1536                 :   }
    1537                 : 
    1538               2 :   if (numitems != 5) {
    1539                 :     printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
    1540               0 :            numitems, result);
    1541               0 :     return NS_ERROR_FAILURE;
    1542                 :   }
    1543                 : 
    1544               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1545                 : 
    1546               2 :   if (NS_FAILED(result)) {
    1547                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 4 items failed. (%d)\n",
    1548               0 :            result);
    1549               0 :     return result;
    1550                 :   }
    1551                 : 
    1552               2 :   if (numitems != 4) {
    1553                 :     printf("ERROR: GetNumberOfRedoItems() expected 4 got %d. (%d)\n",
    1554               0 :            numitems, result);
    1555               0 :     return NS_ERROR_FAILURE;
    1556                 :   }
    1557                 : 
    1558               2 :   result = mgr->Clear();
    1559               2 :   if (NS_FAILED(result)) {
    1560                 :     printf("ERROR: Clear() failed. (%d)\n",
    1561               0 :            result);
    1562               0 :     return result;
    1563                 :   }
    1564                 : 
    1565               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1566                 : 
    1567               2 :   if (NS_FAILED(result)) {
    1568                 :     printf("ERROR: GetNumberOfUndoItems() on cleared undo stack failed. (%d)\n",
    1569               0 :            result);
    1570               0 :     return result;
    1571                 :   }
    1572                 : 
    1573               2 :   if (numitems != 0) {
    1574                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    1575               0 :            numitems, result);
    1576               0 :     return NS_ERROR_FAILURE;
    1577                 :   }
    1578                 : 
    1579               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1580                 : 
    1581               2 :   if (NS_FAILED(result)) {
    1582                 :     printf("ERROR: GetNumberOfRedoItems() on cleared redo stack failed. (%d)\n",
    1583               0 :            result);
    1584               0 :     return result;
    1585                 :   }
    1586                 : 
    1587               2 :   if (numitems != 0) {
    1588                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1589               0 :            numitems, result);
    1590               0 :     return NS_ERROR_FAILURE;
    1591                 :   }
    1592                 : 
    1593               2 :   passed("Undo 4 transactions then clear the undo and redo stacks");
    1594                 : 
    1595                 :   /*******************************************************************
    1596                 :    *
    1597                 :    * Execute 5 transactions.
    1598                 :    *
    1599                 :    *******************************************************************/
    1600                 : 
    1601              12 :   for (i = 1; i <= 5; i++) {
    1602              10 :     tximpl = factory->create(mgr, NONE_FLAG);
    1603                 : 
    1604              10 :     if (!tximpl) {
    1605               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    1606               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1607                 :     }
    1608                 : 
    1609              10 :     tx = 0;
    1610              10 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1611              10 :     if (NS_FAILED(result)) {
    1612                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    1613               0 :              i, result);
    1614               0 :       return result;
    1615                 :     }
    1616                 : 
    1617              10 :     result = mgr->DoTransaction(tx);
    1618              10 :     if (NS_FAILED(result)) {
    1619               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    1620               0 :       return result;
    1621                 :     }
    1622                 : 
    1623              10 :     tx->Release();
    1624                 :   }
    1625                 : 
    1626               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1627                 : 
    1628               2 :   if (NS_FAILED(result)) {
    1629                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
    1630               0 :            result);
    1631               0 :     return result;
    1632                 :   }
    1633                 : 
    1634               2 :   if (numitems != 5) {
    1635                 :     printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
    1636               0 :            numitems, result);
    1637               0 :     return NS_ERROR_FAILURE;
    1638                 :   }
    1639                 : 
    1640               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1641                 : 
    1642               2 :   if (NS_FAILED(result)) {
    1643                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    1644               0 :            result);
    1645               0 :     return result;
    1646                 :   }
    1647                 : 
    1648               2 :   if (numitems != 0) {
    1649                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1650               0 :            numitems, result);
    1651               0 :     return NS_ERROR_FAILURE;
    1652                 :   }
    1653                 : 
    1654               2 :   passed("Execute 5 transactions");
    1655                 : 
    1656                 :   /*******************************************************************
    1657                 :    *
    1658                 :    * Test transaction DoTransaction() error:
    1659                 :    *
    1660                 :    *******************************************************************/
    1661                 : 
    1662               2 :   tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
    1663                 : 
    1664               2 :   if (!tximpl) {
    1665               0 :     printf("ERROR: Failed to allocate transaction.\n");
    1666               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1667                 :   }
    1668                 : 
    1669               2 :   tx = 0;
    1670                 : 
    1671               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1672                 : 
    1673               2 :   if (NS_FAILED(result)) {
    1674               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    1675               0 :     return result;
    1676                 :   }
    1677                 : 
    1678               2 :   u1 = u2 = r1 = r2 = 0;
    1679                 : 
    1680               2 :   result = mgr->PeekUndoStack(&u1);
    1681                 : 
    1682               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    1683                 : 
    1684               2 :   if (NS_FAILED(result)) {
    1685               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    1686               0 :     return result;
    1687                 :   }
    1688                 : 
    1689               2 :   result = mgr->PeekRedoStack(&r1);
    1690                 : 
    1691               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    1692                 : 
    1693               2 :   if (NS_FAILED(result)) {
    1694               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    1695               0 :     return result;
    1696                 :   }
    1697                 : 
    1698               2 :   result = mgr->DoTransaction(tx);
    1699                 : 
    1700               2 :   if (result != NS_ERROR_FAILURE) {
    1701               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    1702               0 :     return result;
    1703                 :   }
    1704                 : 
    1705               2 :   tx->Release();
    1706                 : 
    1707               2 :   result = mgr->PeekUndoStack(&u2);
    1708                 : 
    1709               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    1710                 : 
    1711               2 :   if (NS_FAILED(result)) {
    1712               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    1713               0 :     return result;
    1714                 :   }
    1715                 : 
    1716               2 :   if (u1 != u2) {
    1717               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    1718               0 :     return NS_ERROR_FAILURE;
    1719                 :   }
    1720                 : 
    1721               2 :   result = mgr->PeekRedoStack(&r2);
    1722                 : 
    1723               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    1724                 : 
    1725               2 :   if (NS_FAILED(result)) {
    1726               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    1727               0 :     return result;
    1728                 :   }
    1729                 : 
    1730               2 :   if (r1 != r2) {
    1731               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    1732               0 :     return NS_ERROR_FAILURE;
    1733                 :   }
    1734                 : 
    1735               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1736                 : 
    1737               2 :   if (NS_FAILED(result)) {
    1738                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
    1739               0 :            result);
    1740               0 :     return result;
    1741                 :   }
    1742                 : 
    1743               2 :   if (numitems != 5) {
    1744                 :     printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
    1745               0 :            numitems, result);
    1746               0 :     return NS_ERROR_FAILURE;
    1747                 :   }
    1748                 : 
    1749               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1750                 : 
    1751               2 :   if (NS_FAILED(result)) {
    1752                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
    1753               0 :            result);
    1754               0 :     return result;
    1755                 :   }
    1756                 : 
    1757               2 :   if (numitems != 0) {
    1758                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1759               0 :            numitems, result);
    1760               0 :     return NS_ERROR_FAILURE;
    1761                 :   }
    1762                 : 
    1763               2 :   passed("Test transaction DoTransaction() error");
    1764                 : 
    1765                 :   /*******************************************************************
    1766                 :    *
    1767                 :    * Test transaction UndoTransaction() error:
    1768                 :    *
    1769                 :    *******************************************************************/
    1770                 : 
    1771               2 :   tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
    1772                 : 
    1773               2 :   if (!tximpl) {
    1774               0 :     printf("ERROR: Failed to allocate transaction.\n");
    1775               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1776                 :   }
    1777                 : 
    1778               2 :   tx = 0;
    1779                 : 
    1780               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1781                 : 
    1782               2 :   if (NS_FAILED(result)) {
    1783               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    1784               0 :     return result;
    1785                 :   }
    1786                 : 
    1787               2 :   result = mgr->DoTransaction(tx);
    1788                 : 
    1789               2 :   if (NS_FAILED(result)) {
    1790               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    1791               0 :     return result;
    1792                 :   }
    1793                 : 
    1794               2 :   tx->Release();
    1795                 : 
    1796               2 :   u1 = u2 = r1 = r2 = 0;
    1797                 : 
    1798               2 :   result = mgr->PeekUndoStack(&u1);
    1799                 : 
    1800               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    1801                 : 
    1802               2 :   if (NS_FAILED(result)) {
    1803               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    1804               0 :     return result;
    1805                 :   }
    1806                 : 
    1807               2 :   result = mgr->PeekRedoStack(&r1);
    1808                 : 
    1809               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    1810                 : 
    1811               2 :   if (NS_FAILED(result)) {
    1812               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    1813               0 :     return result;
    1814                 :   }
    1815                 : 
    1816               2 :   result = mgr->UndoTransaction();
    1817                 : 
    1818               2 :   if (result != NS_ERROR_FAILURE) {
    1819               0 :     printf("ERROR: UndoTransaction() returned unexpected error. (%d)\n", result);
    1820               0 :     return result;
    1821                 :   }
    1822                 : 
    1823               2 :   result = mgr->PeekUndoStack(&u2);
    1824                 : 
    1825               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    1826                 : 
    1827               2 :   if (NS_FAILED(result)) {
    1828               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    1829               0 :     return result;
    1830                 :   }
    1831                 : 
    1832               2 :   if (u1 != u2) {
    1833               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    1834               0 :     return NS_ERROR_FAILURE;
    1835                 :   }
    1836                 : 
    1837               2 :   result = mgr->PeekRedoStack(&r2);
    1838                 : 
    1839               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    1840                 : 
    1841               2 :   if (NS_FAILED(result)) {
    1842               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    1843               0 :     return result;
    1844                 :   }
    1845                 : 
    1846               2 :   if (r1 != r2) {
    1847               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    1848               0 :     return NS_ERROR_FAILURE;
    1849                 :   }
    1850                 : 
    1851               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    1852                 : 
    1853               2 :   if (NS_FAILED(result)) {
    1854                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
    1855               0 :            result);
    1856               0 :     return result;
    1857                 :   }
    1858                 : 
    1859               2 :   if (numitems != 6) {
    1860                 :     printf("ERROR: GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
    1861               0 :            numitems, result);
    1862               0 :     return NS_ERROR_FAILURE;
    1863                 :   }
    1864                 : 
    1865               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    1866                 : 
    1867               2 :   if (NS_FAILED(result)) {
    1868                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
    1869               0 :            result);
    1870               0 :     return result;
    1871                 :   }
    1872                 : 
    1873               2 :   if (numitems != 0) {
    1874                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    1875               0 :            numitems, result);
    1876               0 :     return NS_ERROR_FAILURE;
    1877                 :   }
    1878                 : 
    1879               2 :   passed("Test transaction UndoTransaction() error");
    1880                 : 
    1881                 :   /*******************************************************************
    1882                 :    *
    1883                 :    * Test transaction RedoTransaction() error:
    1884                 :    *
    1885                 :    *******************************************************************/
    1886                 : 
    1887               2 :   tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
    1888                 : 
    1889               2 :   if (!tximpl) {
    1890               0 :     printf("ERROR: Failed to allocate transaction.\n");
    1891               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1892                 :   }
    1893                 : 
    1894               2 :   tx = 0;
    1895                 : 
    1896               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1897                 : 
    1898               2 :   if (NS_FAILED(result)) {
    1899                 :     printf("ERROR: QueryInterface() failed for RedoErrorTransaction. (%d)\n",
    1900               0 :            result);
    1901               0 :     return result;
    1902                 :   }
    1903                 : 
    1904               2 :   result = mgr->DoTransaction(tx);
    1905                 : 
    1906               2 :   if (NS_FAILED(result)) {
    1907               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    1908               0 :     return result;
    1909                 :   }
    1910                 : 
    1911               2 :   tx->Release();
    1912                 : 
    1913                 :   //
    1914                 :   // Execute a normal transaction to be used in a later test:
    1915                 :   //
    1916                 : 
    1917               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    1918                 : 
    1919               2 :   if (!tximpl) {
    1920               0 :     printf("ERROR: Failed to allocate transaction.\n");
    1921               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1922                 :   }
    1923                 : 
    1924               2 :   tx = 0;
    1925                 : 
    1926               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    1927                 : 
    1928               2 :   if (NS_FAILED(result)) {
    1929               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    1930               0 :     return result;
    1931                 :   }
    1932                 : 
    1933               2 :   result = mgr->DoTransaction(tx);
    1934                 : 
    1935               2 :   if (NS_FAILED(result)) {
    1936               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    1937               0 :     return result;
    1938                 :   }
    1939                 : 
    1940               2 :   tx->Release();
    1941                 : 
    1942                 :   //
    1943                 :   // Undo the 2 transactions just executed.
    1944                 :   //
    1945                 : 
    1946               6 :   for (i = 1; i <= 2; ++i) {
    1947               4 :     result = mgr->UndoTransaction();
    1948               4 :     if (NS_FAILED(result)) {
    1949               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    1950               0 :       return result;
    1951                 :     }
    1952                 :   }
    1953                 : 
    1954                 :   //
    1955                 :   // The RedoErrorTransaction should now be at the top of the redo stack!
    1956                 :   //
    1957                 : 
    1958               2 :   u1 = u2 = r1 = r2 = 0;
    1959                 : 
    1960               2 :   result = mgr->PeekUndoStack(&u1);
    1961                 : 
    1962               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    1963                 : 
    1964               2 :   if (NS_FAILED(result)) {
    1965               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    1966               0 :     return result;
    1967                 :   }
    1968                 : 
    1969               2 :   result = mgr->PeekRedoStack(&r1);
    1970                 : 
    1971               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    1972                 : 
    1973               2 :   if (NS_FAILED(result)) {
    1974               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    1975               0 :     return result;
    1976                 :   }
    1977                 : 
    1978               2 :   result = mgr->RedoTransaction();
    1979                 : 
    1980               2 :   if (result != NS_ERROR_FAILURE) {
    1981               0 :     printf("ERROR: RedoTransaction() returned unexpected error. (%d)\n", result);
    1982               0 :     return result;
    1983                 :   }
    1984                 : 
    1985               2 :   result = mgr->PeekUndoStack(&u2);
    1986                 : 
    1987               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    1988                 : 
    1989               2 :   if (NS_FAILED(result)) {
    1990               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    1991               0 :     return result;
    1992                 :   }
    1993                 : 
    1994               2 :   if (u1 != u2) {
    1995               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    1996               0 :     return NS_ERROR_FAILURE;
    1997                 :   }
    1998                 : 
    1999               2 :   result = mgr->PeekRedoStack(&r2);
    2000                 : 
    2001               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    2002                 : 
    2003               2 :   if (NS_FAILED(result)) {
    2004               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    2005               0 :     return result;
    2006                 :   }
    2007                 : 
    2008               2 :   if (r1 != r2) {
    2009               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    2010               0 :     return NS_ERROR_FAILURE;
    2011                 :   }
    2012                 : 
    2013               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2014                 : 
    2015               2 :   if (NS_FAILED(result)) {
    2016                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
    2017               0 :            result);
    2018               0 :     return result;
    2019                 :   }
    2020                 : 
    2021               2 :   if (numitems != 6) {
    2022                 :     printf("ERROR: GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
    2023               0 :            numitems, result);
    2024               0 :     return NS_ERROR_FAILURE;
    2025                 :   }
    2026                 : 
    2027               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2028                 : 
    2029               2 :   if (NS_FAILED(result)) {
    2030                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
    2031               0 :            result);
    2032               0 :     return result;
    2033                 :   }
    2034                 : 
    2035               2 :   if (numitems != 2) {
    2036                 :     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
    2037               0 :            numitems, result);
    2038               0 :     return NS_ERROR_FAILURE;
    2039                 :   }
    2040                 : 
    2041               2 :   passed("Test transaction RedoTransaction() error");
    2042                 : 
    2043                 :   /*******************************************************************
    2044                 :    *
    2045                 :    * Make sure that setting the transaction manager's max transaction
    2046                 :    * count to zero, clears both the undo and redo stacks, and executes
    2047                 :    * all new commands without pushing them on the undo stack!
    2048                 :    *
    2049                 :    *******************************************************************/
    2050                 : 
    2051               2 :   result = mgr->SetMaxTransactionCount(0);
    2052                 : 
    2053               2 :   if (NS_FAILED(result)) {
    2054               0 :     printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
    2055               0 :     return result;
    2056                 :   }
    2057                 : 
    2058               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2059                 : 
    2060               2 :   if (NS_FAILED(result)) {
    2061                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2062               0 :            result);
    2063               0 :     return result;
    2064                 :   }
    2065                 : 
    2066               2 :   if (numitems != 0) {
    2067                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2068               0 :            numitems, result);
    2069               0 :     return NS_ERROR_FAILURE;
    2070                 :   }
    2071                 : 
    2072               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2073                 : 
    2074               2 :   if (NS_FAILED(result)) {
    2075                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    2076               0 :            result);
    2077               0 :     return result;
    2078                 :   }
    2079                 : 
    2080               2 :   if (numitems != 0) {
    2081                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    2082               0 :            numitems, result);
    2083               0 :     return NS_ERROR_FAILURE;
    2084                 :   }
    2085                 : 
    2086              42 :   for (i = 1; i <= 20; i++) {
    2087              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    2088                 : 
    2089              40 :     if (!tximpl) {
    2090               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    2091               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2092                 :     }
    2093                 : 
    2094              40 :     tx = 0;
    2095              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    2096              40 :     if (NS_FAILED(result)) {
    2097                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    2098               0 :              i, result);
    2099               0 :       return result;
    2100                 :     }
    2101                 : 
    2102              40 :     result = mgr->DoTransaction(tx);
    2103              40 :     if (NS_FAILED(result)) {
    2104               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    2105               0 :       return result;
    2106                 :     }
    2107                 : 
    2108              40 :     tx->Release();
    2109                 : 
    2110              40 :     result = mgr->GetNumberOfUndoItems(&numitems);
    2111                 : 
    2112              40 :     if (NS_FAILED(result)) {
    2113                 :       printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2114               0 :              result);
    2115               0 :       return result;
    2116                 :     }
    2117                 : 
    2118              40 :     if (numitems != 0) {
    2119                 :       printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2120               0 :              numitems, result);
    2121               0 :       return NS_ERROR_FAILURE;
    2122                 :     }
    2123                 : 
    2124              40 :     result = mgr->GetNumberOfRedoItems(&numitems);
    2125                 : 
    2126              40 :     if (NS_FAILED(result)) {
    2127                 :       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    2128               0 :              result);
    2129               0 :       return result;
    2130                 :     }
    2131                 : 
    2132              40 :     if (numitems != 0) {
    2133                 :       printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    2134               0 :              numitems, result);
    2135               0 :       return NS_ERROR_FAILURE;
    2136                 :     }
    2137                 :   }
    2138                 : 
    2139               2 :   passed("Test max transaction count of zero");
    2140                 : 
    2141                 :   /*******************************************************************
    2142                 :    *
    2143                 :    * Make sure that setting the transaction manager's max transaction
    2144                 :    * count to something greater than the number of transactions on
    2145                 :    * both the undo and redo stacks causes no pruning of the stacks:
    2146                 :    *
    2147                 :    *******************************************************************/
    2148                 : 
    2149               2 :   result = mgr->SetMaxTransactionCount(-1);
    2150                 : 
    2151               2 :   if (NS_FAILED(result)) {
    2152               0 :     printf("ERROR: SetMaxTransactionCount(-1) failed. (%d)\n", result);
    2153               0 :     return result;
    2154                 :   }
    2155                 : 
    2156                 :   // Push 20 transactions on the undo stack:
    2157                 : 
    2158              42 :   for (i = 1; i <= 20; i++) {
    2159              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    2160                 : 
    2161              40 :     if (!tximpl) {
    2162               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    2163               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2164                 :     }
    2165                 : 
    2166              40 :     tx = 0;
    2167              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    2168              40 :     if (NS_FAILED(result)) {
    2169                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    2170               0 :              i, result);
    2171               0 :       return result;
    2172                 :     }
    2173                 : 
    2174              40 :     result = mgr->DoTransaction(tx);
    2175              40 :     if (NS_FAILED(result)) {
    2176               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    2177               0 :       return result;
    2178                 :     }
    2179                 : 
    2180              40 :     tx->Release();
    2181                 : 
    2182              40 :     result = mgr->GetNumberOfUndoItems(&numitems);
    2183                 : 
    2184              40 :     if (NS_FAILED(result)) {
    2185                 :       printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
    2186               0 :              i, result);
    2187               0 :       return result;
    2188                 :     }
    2189                 : 
    2190              40 :     if (numitems != i) {
    2191                 :       printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
    2192               0 :              i, numitems, result);
    2193               0 :       return NS_ERROR_FAILURE;
    2194                 :     }
    2195                 : 
    2196              40 :     result = mgr->GetNumberOfRedoItems(&numitems);
    2197                 : 
    2198              40 :     if (NS_FAILED(result)) {
    2199                 :       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    2200               0 :              result);
    2201               0 :       return result;
    2202                 :     }
    2203                 : 
    2204              40 :     if (numitems != 0) {
    2205                 :       printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    2206               0 :              numitems, result);
    2207               0 :       return NS_ERROR_FAILURE;
    2208                 :     }
    2209                 :   }
    2210                 : 
    2211              22 :   for (i = 1; i <= 10; i++) {
    2212                 : 
    2213              20 :     result = mgr->UndoTransaction();
    2214              20 :     if (NS_FAILED(result)) {
    2215               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    2216               0 :       return result;
    2217                 :     }
    2218                 :   }
    2219               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2220                 : 
    2221               2 :   if (NS_FAILED(result)) {
    2222                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack with 10 items failed. (%d)\n",
    2223               0 :            result);
    2224               0 :     return result;
    2225                 :   }
    2226                 : 
    2227               2 :   if (numitems != 10) {
    2228                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    2229               0 :            numitems, result);
    2230               0 :     return NS_ERROR_FAILURE;
    2231                 :   }
    2232                 : 
    2233               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2234                 : 
    2235               2 :   if (NS_FAILED(result)) {
    2236                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
    2237               0 :            result);
    2238               0 :     return result;
    2239                 :   }
    2240                 : 
    2241               2 :   if (numitems != 10) {
    2242                 :     printf("ERROR: GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
    2243               0 :            numitems, result);
    2244               0 :     return NS_ERROR_FAILURE;
    2245                 :   }
    2246                 : 
    2247               2 :   u1 = u2 = r1 = r2 = 0;
    2248                 : 
    2249               2 :   result = mgr->PeekUndoStack(&u1);
    2250                 : 
    2251               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    2252                 : 
    2253               2 :   if (NS_FAILED(result)) {
    2254               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    2255               0 :     return result;
    2256                 :   }
    2257                 : 
    2258               2 :   result = mgr->PeekRedoStack(&r1);
    2259                 : 
    2260               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    2261                 : 
    2262               2 :   if (NS_FAILED(result)) {
    2263               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    2264               0 :     return result;
    2265                 :   }
    2266                 : 
    2267               2 :   result = mgr->SetMaxTransactionCount(25);
    2268                 : 
    2269               2 :   if (NS_FAILED(result)) {
    2270               0 :     printf("ERROR: SetMaxTransactionCount(25) failed. (%d)\n", result);
    2271               0 :     return result;
    2272                 :   }
    2273                 : 
    2274               2 :   result = mgr->PeekUndoStack(&u2);
    2275                 : 
    2276               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    2277                 : 
    2278               2 :   if (NS_FAILED(result)) {
    2279               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    2280               0 :     return result;
    2281                 :   }
    2282                 : 
    2283               2 :   if (u1 != u2) {
    2284               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    2285               0 :     return NS_ERROR_FAILURE;
    2286                 :   }
    2287                 : 
    2288               2 :   result = mgr->PeekRedoStack(&r2);
    2289                 : 
    2290               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    2291                 : 
    2292               2 :   if (NS_FAILED(result)) {
    2293               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    2294               0 :     return result;
    2295                 :   }
    2296                 : 
    2297               2 :   if (r1 != r2) {
    2298               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    2299               0 :     return NS_ERROR_FAILURE;
    2300                 :   }
    2301                 : 
    2302               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2303                 : 
    2304               2 :   if (NS_FAILED(result)) {
    2305                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
    2306               0 :            result);
    2307               0 :     return result;
    2308                 :   }
    2309                 : 
    2310               2 :   if (numitems != 10) {
    2311                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    2312               0 :            numitems, result);
    2313               0 :     return NS_ERROR_FAILURE;
    2314                 :   }
    2315                 : 
    2316               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2317                 : 
    2318               2 :   if (NS_FAILED(result)) {
    2319                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
    2320               0 :            result);
    2321               0 :     return result;
    2322                 :   }
    2323                 : 
    2324               2 :   if (numitems != 10) {
    2325                 :     printf("ERROR: GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
    2326               0 :            numitems, result);
    2327               0 :     return NS_ERROR_FAILURE;
    2328                 :   }
    2329                 : 
    2330               2 :   passed("Test SetMaxTransactionCount() greater than num stack items");
    2331                 : 
    2332                 :   /*******************************************************************
    2333                 :    *
    2334                 :    * Test undo stack pruning by setting the transaction
    2335                 :    * manager's max transaction count to a number lower than the
    2336                 :    * number of transactions on both the undo and redo stacks:
    2337                 :    *
    2338                 :    *******************************************************************/
    2339                 : 
    2340               2 :   u1 = u2 = r1 = r2 = 0;
    2341                 : 
    2342               2 :   result = mgr->PeekUndoStack(&u1);
    2343                 : 
    2344               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    2345                 : 
    2346               2 :   if (NS_FAILED(result)) {
    2347               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    2348               0 :     return result;
    2349                 :   }
    2350                 : 
    2351               2 :   result = mgr->PeekRedoStack(&r1);
    2352                 : 
    2353               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    2354                 : 
    2355               2 :   if (NS_FAILED(result)) {
    2356               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    2357               0 :     return result;
    2358                 :   }
    2359                 : 
    2360               2 :   result = mgr->SetMaxTransactionCount(15);
    2361                 : 
    2362               2 :   if (NS_FAILED(result)) {
    2363               0 :     printf("ERROR: SetMaxTransactionCount(15) failed. (%d)\n", result);
    2364               0 :     return result;
    2365                 :   }
    2366                 : 
    2367               2 :   result = mgr->PeekUndoStack(&u2);
    2368                 : 
    2369               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    2370                 : 
    2371               2 :   if (NS_FAILED(result)) {
    2372               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    2373               0 :     return result;
    2374                 :   }
    2375                 : 
    2376               2 :   if (u1 != u2) {
    2377               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    2378               0 :     return NS_ERROR_FAILURE;
    2379                 :   }
    2380                 : 
    2381               2 :   result = mgr->PeekRedoStack(&r2);
    2382                 : 
    2383               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    2384                 : 
    2385               2 :   if (NS_FAILED(result)) {
    2386               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    2387               0 :     return result;
    2388                 :   }
    2389                 : 
    2390               2 :   if (r1 != r2) {
    2391               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    2392               0 :     return NS_ERROR_FAILURE;
    2393                 :   }
    2394                 : 
    2395               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2396                 : 
    2397               2 :   if (NS_FAILED(result)) {
    2398                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
    2399               0 :            result);
    2400               0 :     return result;
    2401                 :   }
    2402                 : 
    2403               2 :   if (numitems != 5) {
    2404                 :     printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
    2405               0 :            numitems, result);
    2406               0 :     return NS_ERROR_FAILURE;
    2407                 :   }
    2408                 : 
    2409               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2410                 : 
    2411               2 :   if (NS_FAILED(result)) {
    2412                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
    2413               0 :            result);
    2414               0 :     return result;
    2415                 :   }
    2416                 : 
    2417               2 :   if (numitems != 10) {
    2418                 :     printf("ERROR: GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
    2419               0 :            numitems, result);
    2420               0 :     return NS_ERROR_FAILURE;
    2421                 :   }
    2422                 : 
    2423               2 :   passed("Test SetMaxTransactionCount() pruning undo stack");
    2424                 : 
    2425                 :   /*******************************************************************
    2426                 :    *
    2427                 :    * Test redo stack pruning by setting the transaction
    2428                 :    * manager's max transaction count to a number lower than the
    2429                 :    * number of transactions on both the undo and redo stacks:
    2430                 :    *
    2431                 :    *******************************************************************/
    2432                 : 
    2433               2 :   u1 = u2 = r1 = r2 = 0;
    2434                 : 
    2435               2 :   result = mgr->PeekUndoStack(&u1);
    2436                 : 
    2437               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    2438                 : 
    2439               2 :   if (NS_FAILED(result)) {
    2440               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    2441               0 :     return result;
    2442                 :   }
    2443                 : 
    2444               2 :   result = mgr->PeekRedoStack(&r1);
    2445                 : 
    2446               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    2447                 : 
    2448               2 :   if (NS_FAILED(result)) {
    2449               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    2450               0 :     return result;
    2451                 :   }
    2452                 : 
    2453               2 :   result = mgr->SetMaxTransactionCount(5);
    2454                 : 
    2455               2 :   if (NS_FAILED(result)) {
    2456               0 :     printf("ERROR: SetMaxTransactionCount(5) failed. (%d)\n", result);
    2457               0 :     return result;
    2458                 :   }
    2459                 : 
    2460               2 :   result = mgr->PeekUndoStack(&u2);
    2461                 : 
    2462               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    2463                 : 
    2464               2 :   if (NS_FAILED(result)) {
    2465               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    2466               0 :     return result;
    2467                 :   }
    2468                 : 
    2469               2 :   if (u2) {
    2470               0 :     printf("ERROR: Unexpected item at top of undo stack. (%d)\n", result);
    2471               0 :     return NS_ERROR_FAILURE;
    2472                 :   }
    2473                 : 
    2474               2 :   result = mgr->PeekRedoStack(&r2);
    2475                 : 
    2476               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    2477                 : 
    2478               2 :   if (NS_FAILED(result)) {
    2479               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    2480               0 :     return result;
    2481                 :   }
    2482                 : 
    2483               2 :   if (r1 != r2) {
    2484               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    2485               0 :     return NS_ERROR_FAILURE;
    2486                 :   }
    2487                 : 
    2488               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2489                 : 
    2490               2 :   if (NS_FAILED(result)) {
    2491                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2492               0 :            result);
    2493               0 :     return result;
    2494                 :   }
    2495                 : 
    2496               2 :   if (numitems != 0) {
    2497                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2498               0 :            numitems, result);
    2499               0 :     return NS_ERROR_FAILURE;
    2500                 :   }
    2501                 : 
    2502               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2503                 : 
    2504               2 :   if (NS_FAILED(result)) {
    2505                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 5 items failed. (%d)\n",
    2506               0 :            result);
    2507               0 :     return result;
    2508                 :   }
    2509                 : 
    2510               2 :   if (numitems != 5) {
    2511                 :     printf("ERROR: GetNumberOfRedoItems() expected 5 got %d. (%d)\n",
    2512               0 :            numitems, result);
    2513               0 :     return NS_ERROR_FAILURE;
    2514                 :   }
    2515                 : 
    2516               2 :   passed("Test SetMaxTransactionCount() pruning redo stack");
    2517                 : 
    2518                 :   /*******************************************************************
    2519                 :    *
    2520                 :    * Release the transaction manager. Any transactions on the undo
    2521                 :    * and redo stack should automatically be released:
    2522                 :    *
    2523                 :    *******************************************************************/
    2524                 : 
    2525               2 :   result = mgr->SetMaxTransactionCount(-1);
    2526                 : 
    2527               2 :   if (NS_FAILED(result)) {
    2528               0 :     printf("ERROR: SetMaxTransactionCount(-1) failed. (%d)\n", result);
    2529               0 :     return result;
    2530                 :   }
    2531                 : 
    2532                 :   // Push 20 transactions on the undo stack:
    2533                 : 
    2534              42 :   for (i = 1; i <= 20; i++) {
    2535              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    2536                 : 
    2537              40 :     if (!tximpl) {
    2538               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    2539               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2540                 :     }
    2541                 : 
    2542              40 :     tx = 0;
    2543              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    2544              40 :     if (NS_FAILED(result)) {
    2545                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    2546               0 :              i, result);
    2547               0 :       return result;
    2548                 :     }
    2549                 : 
    2550              40 :     result = mgr->DoTransaction(tx);
    2551              40 :     if (NS_FAILED(result)) {
    2552               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    2553               0 :       return result;
    2554                 :     }
    2555                 : 
    2556              40 :     tx->Release();
    2557                 : 
    2558              40 :     result = mgr->GetNumberOfUndoItems(&numitems);
    2559                 : 
    2560              40 :     if (NS_FAILED(result)) {
    2561                 :       printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
    2562               0 :              i, result);
    2563               0 :       return result;
    2564                 :     }
    2565                 : 
    2566              40 :     if (numitems != i) {
    2567                 :       printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
    2568               0 :              i, numitems, result);
    2569               0 :       return NS_ERROR_FAILURE;
    2570                 :     }
    2571                 : 
    2572              40 :     result = mgr->GetNumberOfRedoItems(&numitems);
    2573                 : 
    2574              40 :     if (NS_FAILED(result)) {
    2575                 :       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    2576               0 :              result);
    2577               0 :       return result;
    2578                 :     }
    2579                 : 
    2580              40 :     if (numitems != 0) {
    2581                 :       printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    2582               0 :              numitems, result);
    2583               0 :       return NS_ERROR_FAILURE;
    2584                 :     }
    2585                 :   }
    2586                 : 
    2587              22 :   for (i = 1; i <= 10; i++) {
    2588                 : 
    2589              20 :     result = mgr->UndoTransaction();
    2590              20 :     if (NS_FAILED(result)) {
    2591               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    2592               0 :       return result;
    2593                 :     }
    2594                 :   }
    2595               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2596                 : 
    2597               2 :   if (NS_FAILED(result)) {
    2598                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
    2599               0 :            result);
    2600               0 :     return result;
    2601                 :   }
    2602                 : 
    2603               2 :   if (numitems != 10) {
    2604                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    2605               0 :            numitems, result);
    2606               0 :     return NS_ERROR_FAILURE;
    2607                 :   }
    2608                 : 
    2609               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    2610                 : 
    2611               2 :   if (NS_FAILED(result)) {
    2612                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
    2613               0 :            result);
    2614               0 :     return result;
    2615                 :   }
    2616                 : 
    2617               2 :   if (numitems != 10) {
    2618                 :     printf("ERROR: GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
    2619               0 :            numitems, result);
    2620               0 :     return NS_ERROR_FAILURE;
    2621                 :   }
    2622                 : 
    2623               2 :   result = mgr->Clear();
    2624               2 :   if (NS_FAILED(result)) {
    2625               0 :     printf("ERROR: Clear() failed. (%d)\n", result);
    2626               0 :     return result;
    2627                 :   }
    2628                 : 
    2629               2 :   passed("Release the transaction manager");
    2630                 : 
    2631                 :   /*******************************************************************
    2632                 :    *
    2633                 :    * Make sure number of transactions created matches number of
    2634                 :    * transactions destroyed!
    2635                 :    *
    2636                 :    *******************************************************************/
    2637                 : 
    2638               2 :   if (sConstructorCount != sDestructorCount) {
    2639                 :     printf("ERROR: Transaction constructor count (%d) != destructor count (%d).\n",
    2640               0 :            sConstructorCount, sDestructorCount);
    2641               0 :     return NS_ERROR_FAILURE;
    2642                 :   }
    2643                 : 
    2644               2 :   passed("Number of transactions created and destroyed match");
    2645               2 :   passed("%d transactions processed during quick test", sConstructorCount);
    2646                 : 
    2647               2 :   return NS_OK;
    2648                 : }
    2649                 : 
    2650                 : nsresult
    2651               1 : simple_test()
    2652                 : {
    2653                 :   /*******************************************************************
    2654                 :    *
    2655                 :    * Initialize globals for test.
    2656                 :    *
    2657                 :    *******************************************************************/
    2658               1 :   reset_globals();
    2659               1 :   sDestructorOrderArr = sSimpleTestDestructorOrderArr;
    2660               1 :   sDoOrderArr         = sSimpleTestDoOrderArr;
    2661               1 :   sUndoOrderArr       = sSimpleTestUndoOrderArr;
    2662               1 :   sRedoOrderArr       = sSimpleTestRedoOrderArr;
    2663                 : 
    2664                 :   /*******************************************************************
    2665                 :    *
    2666                 :    * Run the quick test.
    2667                 :    *
    2668                 :    *******************************************************************/
    2669                 : 
    2670               1 :   printf("\n-----------------------------------------------------\n");
    2671               1 :   printf("- Begin Simple Transaction Test:\n");
    2672               1 :   printf("-----------------------------------------------------\n");
    2673                 : 
    2674               1 :   SimpleTransactionFactory factory;
    2675                 : 
    2676               1 :   return quick_test(&factory);
    2677                 : }
    2678                 : 
    2679                 : nsresult
    2680               1 : aggregation_test()
    2681                 : {
    2682                 :   /*******************************************************************
    2683                 :    *
    2684                 :    * Initialize globals for test.
    2685                 :    *
    2686                 :    *******************************************************************/
    2687                 : 
    2688               1 :   reset_globals();
    2689               1 :   sDestructorOrderArr = sAggregateTestDestructorOrderArr;
    2690               1 :   sDoOrderArr         = sAggregateTestDoOrderArr;
    2691               1 :   sUndoOrderArr       = sAggregateTestUndoOrderArr;
    2692               1 :   sRedoOrderArr       = sAggregateTestRedoOrderArr;
    2693                 : 
    2694                 :   /*******************************************************************
    2695                 :    *
    2696                 :    * Run the quick test.
    2697                 :    *
    2698                 :    *******************************************************************/
    2699                 : 
    2700               1 :   printf("\n-----------------------------------------------------\n");
    2701               1 :   printf("- Begin Aggregate Transaction Test:\n");
    2702               1 :   printf("-----------------------------------------------------\n");
    2703                 : 
    2704               1 :   AggregateTransactionFactory factory(3, 2);
    2705                 : 
    2706               1 :   return quick_test(&factory);
    2707                 : }
    2708                 : 
    2709                 : /**
    2710                 :  * Test behaviors in batch mode.
    2711                 :  **/
    2712                 : nsresult
    2713               2 : quick_batch_test(TestTransactionFactory *factory)
    2714                 : {
    2715                 :   nsresult result;
    2716                 : 
    2717                 :   /*******************************************************************
    2718                 :    *
    2719                 :    * Create a transaction manager implementation:
    2720                 :    *
    2721                 :    *******************************************************************/
    2722                 : 
    2723                 :   nsCOMPtr<nsITransactionManager> mgr =
    2724               4 :     do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
    2725               2 :   if (NS_FAILED(result) || !mgr) {
    2726               0 :     printf("ERROR: Failed to create Transaction Manager instance.\n");
    2727               0 :     return NS_ERROR_OUT_OF_MEMORY;
    2728                 :   }
    2729                 : 
    2730               2 :   passed("Create transaction manager instance");
    2731                 : 
    2732                 :   PRInt32 numitems;
    2733                 : 
    2734                 :   /*******************************************************************
    2735                 :    *
    2736                 :    * Make sure an unbalanced call to EndBatch() with empty undo stack
    2737                 :    * throws an error!
    2738                 :    *
    2739                 :    *******************************************************************/
    2740                 : 
    2741               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2742                 : 
    2743               2 :   if (NS_FAILED(result)) {
    2744                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2745               0 :            result);
    2746               0 :     return result;
    2747                 :   }
    2748                 : 
    2749               2 :   if (numitems != 0) {
    2750                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2751               0 :            numitems, result);
    2752               0 :     return NS_ERROR_FAILURE;
    2753                 :   }
    2754                 : 
    2755               2 :   result = mgr->EndBatch();
    2756                 : 
    2757               2 :   if (result != NS_ERROR_FAILURE) {
    2758               0 :     printf("ERROR: EndBatch() returned unexpected status. (%d)\n", result);
    2759               0 :     return result;
    2760                 :   }
    2761                 : 
    2762               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2763                 : 
    2764               2 :   if (NS_FAILED(result)) {
    2765                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2766               0 :            result);
    2767               0 :     return result;
    2768                 :   }
    2769                 : 
    2770               2 :   if (numitems != 0) {
    2771                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2772               0 :            numitems, result);
    2773               0 :     return NS_ERROR_FAILURE;
    2774                 :   }
    2775                 : 
    2776               2 :   passed("Test unbalanced EndBatch() with empty undo stack");
    2777                 : 
    2778                 :   /*******************************************************************
    2779                 :    *
    2780                 :    * Make sure that an empty batch is not added to the undo stack
    2781                 :    * when it is closed.
    2782                 :    *
    2783                 :    *******************************************************************/
    2784                 : 
    2785               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2786                 : 
    2787               2 :   if (NS_FAILED(result)) {
    2788                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2789               0 :            result);
    2790               0 :     return result;
    2791                 :   }
    2792                 : 
    2793               2 :   if (numitems != 0) {
    2794                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2795               0 :            numitems, result);
    2796               0 :     return NS_ERROR_FAILURE;
    2797                 :   }
    2798                 : 
    2799               2 :   result = mgr->BeginBatch();
    2800                 : 
    2801               2 :   if (NS_FAILED(result)) {
    2802               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    2803               0 :     return result;
    2804                 :   }
    2805                 : 
    2806               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2807                 : 
    2808               2 :   if (NS_FAILED(result)) {
    2809                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2810               0 :            result);
    2811               0 :     return result;
    2812                 :   }
    2813                 : 
    2814               2 :   if (numitems != 0) {
    2815                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2816               0 :            numitems, result);
    2817               0 :     return NS_ERROR_FAILURE;
    2818                 :   }
    2819                 : 
    2820               2 :   result = mgr->EndBatch();
    2821                 : 
    2822               2 :   if (NS_FAILED(result)) {
    2823               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    2824               0 :     return result;
    2825                 :   }
    2826                 : 
    2827               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2828                 : 
    2829               2 :   if (NS_FAILED(result)) {
    2830                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2831               0 :            result);
    2832               0 :     return result;
    2833                 :   }
    2834                 : 
    2835               2 :   if (numitems != 0) {
    2836                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2837               0 :            numitems, result);
    2838               0 :     return NS_ERROR_FAILURE;
    2839                 :   }
    2840                 : 
    2841               2 :   passed("Test empty batch");
    2842                 : 
    2843                 :   PRInt32 i;
    2844                 :   TestTransaction *tximpl;
    2845                 :   nsITransaction *tx;
    2846                 : 
    2847                 :   /*******************************************************************
    2848                 :    *
    2849                 :    * Execute 20 transactions. Afterwards, we should have 1
    2850                 :    * transaction on the undo stack:
    2851                 :    *
    2852                 :    *******************************************************************/
    2853                 : 
    2854               2 :   result = mgr->BeginBatch();
    2855                 : 
    2856               2 :   if (NS_FAILED(result)) {
    2857               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    2858               0 :     return result;
    2859                 :   }
    2860                 : 
    2861              42 :   for (i = 1; i <= 20; i++) {
    2862              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    2863                 : 
    2864              40 :     if (!tximpl) {
    2865               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    2866               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2867                 :     }
    2868                 : 
    2869              40 :     tx = 0;
    2870              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    2871              40 :     if (NS_FAILED(result)) {
    2872                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    2873               0 :              i, result);
    2874               0 :       return result;
    2875                 :     }
    2876                 : 
    2877              40 :     result = mgr->DoTransaction(tx);
    2878              40 :     if (NS_FAILED(result)) {
    2879               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    2880               0 :       return result;
    2881                 :     }
    2882                 : 
    2883              40 :     tx->Release();
    2884                 :   }
    2885                 : 
    2886               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2887                 : 
    2888               2 :   if (NS_FAILED(result)) {
    2889                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    2890               0 :            result);
    2891               0 :     return result;
    2892                 :   }
    2893                 : 
    2894               2 :   if (numitems != 0) {
    2895                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    2896               0 :            numitems, result);
    2897               0 :     return NS_ERROR_FAILURE;
    2898                 :   }
    2899                 : 
    2900               2 :   result = mgr->EndBatch();
    2901                 : 
    2902               2 :   if (NS_FAILED(result)) {
    2903               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    2904               0 :     return result;
    2905                 :   }
    2906                 : 
    2907               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    2908                 : 
    2909               2 :   if (NS_FAILED(result)) {
    2910                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    2911               0 :            result);
    2912               0 :     return result;
    2913                 :   }
    2914                 : 
    2915               2 :   if (numitems != 1) {
    2916                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    2917               0 :            numitems, result);
    2918               0 :     return NS_ERROR_FAILURE;
    2919                 :   }
    2920                 : 
    2921               2 :   passed("Execute 20 batched transactions");
    2922                 : 
    2923                 :   nsITransaction *u1, *u2;
    2924                 :   nsITransaction *r1, *r2;
    2925                 : 
    2926                 :   /*******************************************************************
    2927                 :    *
    2928                 :    * Execute 20 transient transactions. Afterwards, we should still
    2929                 :    * have the same transaction on the undo stack:
    2930                 :    *
    2931                 :    *******************************************************************/
    2932                 : 
    2933               2 :   u1 = u2 = r1 = r2 = 0;
    2934                 : 
    2935               2 :   result = mgr->PeekUndoStack(&u1);
    2936                 : 
    2937               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    2938                 : 
    2939               2 :   if (NS_FAILED(result)) {
    2940               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    2941               0 :     return result;
    2942                 :   }
    2943                 : 
    2944               2 :   result = mgr->PeekRedoStack(&r1);
    2945                 : 
    2946               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    2947                 : 
    2948               2 :   if (NS_FAILED(result)) {
    2949               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    2950               0 :     return result;
    2951                 :   }
    2952                 : 
    2953               2 :   result = mgr->BeginBatch();
    2954                 : 
    2955               2 :   if (NS_FAILED(result)) {
    2956               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    2957               0 :     return result;
    2958                 :   }
    2959                 : 
    2960              42 :   for (i = 1; i <= 20; i++) {
    2961              40 :     tximpl = factory->create(mgr, TRANSIENT_FLAG);
    2962                 : 
    2963              40 :     if (!tximpl) {
    2964               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    2965               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2966                 :     }
    2967                 : 
    2968              40 :     tx = 0;
    2969              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    2970              40 :     if (NS_FAILED(result)) {
    2971                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    2972               0 :              i, result);
    2973               0 :       return result;
    2974                 :     }
    2975                 : 
    2976              40 :     result = mgr->DoTransaction(tx);
    2977              40 :     if (NS_FAILED(result)) {
    2978               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    2979               0 :       return result;
    2980                 :     }
    2981                 : 
    2982              40 :     tx->Release();
    2983                 :   }
    2984                 : 
    2985               2 :   result = mgr->EndBatch();
    2986                 : 
    2987               2 :   if (NS_FAILED(result)) {
    2988               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    2989               0 :     return result;
    2990                 :   }
    2991                 : 
    2992               2 :   result = mgr->PeekUndoStack(&u2);
    2993                 : 
    2994               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    2995                 : 
    2996               2 :   if (NS_FAILED(result)) {
    2997               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    2998               0 :     return result;
    2999                 :   }
    3000                 : 
    3001               2 :   if (u1 != u2) {
    3002               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    3003               0 :     return NS_ERROR_FAILURE;
    3004                 :   }
    3005                 : 
    3006               2 :   result = mgr->PeekRedoStack(&r2);
    3007                 : 
    3008               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    3009                 : 
    3010               2 :   if (NS_FAILED(result)) {
    3011               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    3012               0 :     return result;
    3013                 :   }
    3014                 : 
    3015               2 :   if (r1 != r2) {
    3016               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    3017               0 :     return NS_ERROR_FAILURE;
    3018                 :   }
    3019                 : 
    3020               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3021                 : 
    3022               2 :   if (NS_FAILED(result)) {
    3023                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3024               0 :            result);
    3025               0 :     return result;
    3026                 :   }
    3027                 : 
    3028               2 :   if (numitems != 1) {
    3029                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3030               0 :            numitems, result);
    3031               0 :     return NS_ERROR_FAILURE;
    3032                 :   }
    3033                 : 
    3034               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3035                 : 
    3036               2 :   if (NS_FAILED(result)) {
    3037                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    3038               0 :            result);
    3039               0 :     return result;
    3040                 :   }
    3041                 : 
    3042               2 :   if (numitems != 0) {
    3043                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    3044               0 :            numitems, result);
    3045               0 :     return NS_ERROR_FAILURE;
    3046                 :   }
    3047                 : 
    3048               2 :   passed("Execute 20 batched transient transactions");
    3049                 : 
    3050                 :   /*******************************************************************
    3051                 :    *
    3052                 :    * Test nested batching. Afterwards, we should have 2 transactions
    3053                 :    * on the undo stack:
    3054                 :    *
    3055                 :    *******************************************************************/
    3056                 : 
    3057               2 :   result = mgr->BeginBatch();
    3058                 : 
    3059               2 :   if (NS_FAILED(result)) {
    3060               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3061               0 :     return result;
    3062                 :   }
    3063                 : 
    3064               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    3065                 : 
    3066               2 :   if (!tximpl) {
    3067               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3068               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3069                 :   }
    3070                 : 
    3071               2 :   tx = 0;
    3072               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3073               2 :   if (NS_FAILED(result)) {
    3074               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3075               0 :     return result;
    3076                 :   }
    3077                 : 
    3078               2 :   result = mgr->DoTransaction(tx);
    3079               2 :   if (NS_FAILED(result)) {
    3080               0 :     printf("ERROR: Failed to execute transaction. (%d)\n", result);
    3081               0 :     return result;
    3082                 :   }
    3083                 : 
    3084               2 :   tx->Release();
    3085                 : 
    3086               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3087                 : 
    3088               2 :   if (NS_FAILED(result)) {
    3089                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3090               0 :            result);
    3091               0 :     return result;
    3092                 :   }
    3093                 : 
    3094               2 :   if (numitems != 1) {
    3095                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3096               0 :            numitems, result);
    3097               0 :     return NS_ERROR_FAILURE;
    3098                 :   }
    3099                 : 
    3100               2 :   result = mgr->BeginBatch();
    3101                 : 
    3102               2 :   if (NS_FAILED(result)) {
    3103               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3104               0 :     return result;
    3105                 :   }
    3106                 : 
    3107               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    3108                 : 
    3109               2 :   if (!tximpl) {
    3110               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3111               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3112                 :   }
    3113                 : 
    3114               2 :   tx = 0;
    3115               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3116               2 :   if (NS_FAILED(result)) {
    3117               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3118               0 :     return result;
    3119                 :   }
    3120                 : 
    3121               2 :   result = mgr->DoTransaction(tx);
    3122               2 :   if (NS_FAILED(result)) {
    3123               0 :     printf("ERROR: Failed to execute transaction. (%d)\n", result);
    3124               0 :     return result;
    3125                 :   }
    3126                 : 
    3127               2 :   tx->Release();
    3128                 : 
    3129               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3130                 : 
    3131               2 :   if (NS_FAILED(result)) {
    3132                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3133               0 :            result);
    3134               0 :     return result;
    3135                 :   }
    3136                 : 
    3137               2 :   if (numitems != 1) {
    3138                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3139               0 :            numitems, result);
    3140               0 :     return NS_ERROR_FAILURE;
    3141                 :   }
    3142                 : 
    3143               2 :   result = mgr->BeginBatch();
    3144                 : 
    3145               2 :   if (NS_FAILED(result)) {
    3146               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3147               0 :     return result;
    3148                 :   }
    3149                 : 
    3150               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    3151                 : 
    3152               2 :   if (!tximpl) {
    3153               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3154               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3155                 :   }
    3156                 : 
    3157               2 :   tx = 0;
    3158               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3159               2 :   if (NS_FAILED(result)) {
    3160               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3161               0 :     return result;
    3162                 :   }
    3163                 : 
    3164               2 :   result = mgr->DoTransaction(tx);
    3165               2 :   if (NS_FAILED(result)) {
    3166               0 :     printf("ERROR: Failed to execute transaction. (%d)\n", result);
    3167               0 :     return result;
    3168                 :   }
    3169                 : 
    3170               2 :   tx->Release();
    3171                 : 
    3172               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3173                 : 
    3174               2 :   if (NS_FAILED(result)) {
    3175                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3176               0 :            result);
    3177               0 :     return result;
    3178                 :   }
    3179                 : 
    3180               2 :   if (numitems != 1) {
    3181                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3182               0 :            numitems, result);
    3183               0 :     return NS_ERROR_FAILURE;
    3184                 :   }
    3185                 : 
    3186               2 :   result = mgr->EndBatch();
    3187                 : 
    3188               2 :   if (NS_FAILED(result)) {
    3189               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3190               0 :     return result;
    3191                 :   }
    3192                 : 
    3193               2 :   result = mgr->EndBatch();
    3194                 : 
    3195               2 :   if (NS_FAILED(result)) {
    3196               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3197               0 :     return result;
    3198                 :   }
    3199                 : 
    3200               2 :   result = mgr->EndBatch();
    3201                 : 
    3202               2 :   if (NS_FAILED(result)) {
    3203               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3204               0 :     return result;
    3205                 :   }
    3206                 : 
    3207               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3208                 : 
    3209               2 :   if (NS_FAILED(result)) {
    3210                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
    3211               0 :            result);
    3212               0 :     return result;
    3213                 :   }
    3214                 : 
    3215               2 :   if (numitems != 2) {
    3216                 :     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
    3217               0 :            numitems, result);
    3218               0 :     return NS_ERROR_FAILURE;
    3219                 :   }
    3220                 : 
    3221               2 :   passed("Test nested batched transactions");
    3222                 : 
    3223                 :   /*******************************************************************
    3224                 :    *
    3225                 :    * Undo 2 batch transactions. Afterwards, we should have 0
    3226                 :    * transactions on the undo stack and 2 on the redo stack.
    3227                 :    *
    3228                 :    *******************************************************************/
    3229                 : 
    3230               6 :   for (i = 1; i <= 2; ++i) {
    3231               4 :     result = mgr->UndoTransaction();
    3232               4 :     if (NS_FAILED(result)) {
    3233               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    3234               0 :       return result;
    3235                 :     }
    3236                 :   }
    3237                 : 
    3238               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3239                 : 
    3240               2 :   if (NS_FAILED(result)) {
    3241                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    3242               0 :            result);
    3243               0 :     return result;
    3244                 :   }
    3245                 : 
    3246               2 :   if (numitems != 0) {
    3247                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    3248               0 :            numitems, result);
    3249               0 :     return NS_ERROR_FAILURE;
    3250                 :   }
    3251                 : 
    3252               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3253                 : 
    3254               2 :   if (NS_FAILED(result)) {
    3255                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
    3256               0 :            result);
    3257               0 :     return result;
    3258                 :   }
    3259                 : 
    3260               2 :   if (numitems != 2) {
    3261                 :     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
    3262               0 :            numitems, result);
    3263               0 :     return NS_ERROR_FAILURE;
    3264                 :   }
    3265                 : 
    3266               2 :   passed("Undo 2 batch transactions");
    3267                 : 
    3268                 :   /*******************************************************************
    3269                 :    *
    3270                 :    * Redo 2 batch transactions. Afterwards, we should have 2
    3271                 :    * transactions on the undo stack and 0 on the redo stack.
    3272                 :    *
    3273                 :    *******************************************************************/
    3274                 : 
    3275               6 :   for (i = 1; i <= 2; ++i) {
    3276               4 :     result = mgr->RedoTransaction();
    3277               4 :     if (NS_FAILED(result)) {
    3278               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    3279               0 :       return result;
    3280                 :     }
    3281                 :   }
    3282                 : 
    3283               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3284                 : 
    3285               2 :   if (NS_FAILED(result)) {
    3286                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
    3287               0 :            result);
    3288               0 :     return result;
    3289                 :   }
    3290                 : 
    3291               2 :   if (numitems != 2) {
    3292                 :     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
    3293               0 :            numitems, result);
    3294               0 :     return NS_ERROR_FAILURE;
    3295                 :   }
    3296                 : 
    3297               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3298                 : 
    3299               2 :   if (NS_FAILED(result)) {
    3300                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    3301               0 :            result);
    3302               0 :     return result;
    3303                 :   }
    3304                 : 
    3305               2 :   if (numitems != 0) {
    3306                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    3307               0 :            numitems, result);
    3308               0 :     return NS_ERROR_FAILURE;
    3309                 :   }
    3310                 : 
    3311               2 :   passed("Redo 2 batch transactions");
    3312                 : 
    3313                 :   /*******************************************************************
    3314                 :    *
    3315                 :    * Call undo. Afterwards, we should have 1 transaction
    3316                 :    * on the undo stack, and 1 on the redo stack:
    3317                 :    *
    3318                 :    *******************************************************************/
    3319                 : 
    3320               2 :   result = mgr->UndoTransaction();
    3321                 : 
    3322               2 :   if (NS_FAILED(result)) {
    3323               0 :     printf("ERROR: Failed to undo transaction. (%d)\n", result);
    3324               0 :     return result;
    3325                 :   }
    3326                 : 
    3327               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3328                 : 
    3329               2 :   if (NS_FAILED(result)) {
    3330                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3331               0 :            result);
    3332               0 :     return result;
    3333                 :   }
    3334                 : 
    3335               2 :   if (numitems != 1) {
    3336                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3337               0 :            numitems, result);
    3338               0 :     return NS_ERROR_FAILURE;
    3339                 :   }
    3340                 : 
    3341               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3342                 : 
    3343               2 :   if (NS_FAILED(result)) {
    3344                 :     printf("ERROR: GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
    3345               0 :            result);
    3346               0 :     return result;
    3347                 :   }
    3348                 : 
    3349               2 :   if (numitems != 1) {
    3350                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3351               0 :            numitems, result);
    3352               0 :     return NS_ERROR_FAILURE;
    3353                 :   }
    3354                 : 
    3355               2 :   passed("Undo a batched transaction that was redone");
    3356                 : 
    3357                 :   /*******************************************************************
    3358                 :    *
    3359                 :    * Make sure an unbalanced call to EndBatch() throws an error and
    3360                 :    * doesn't affect the undo and redo stacks!
    3361                 :    *
    3362                 :    *******************************************************************/
    3363                 : 
    3364               2 :   result = mgr->EndBatch();
    3365                 : 
    3366               2 :   if (result != NS_ERROR_FAILURE) {
    3367               0 :     printf("ERROR: EndBatch() returned unexpected status. (%d)\n", result);
    3368               0 :     return result;
    3369                 :   }
    3370                 : 
    3371               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3372                 : 
    3373               2 :   if (NS_FAILED(result)) {
    3374                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3375               0 :            result);
    3376               0 :     return result;
    3377                 :   }
    3378                 : 
    3379               2 :   if (numitems != 1) {
    3380                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3381               0 :            numitems, result);
    3382               0 :     return NS_ERROR_FAILURE;
    3383                 :   }
    3384                 : 
    3385               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3386                 : 
    3387               2 :   if (NS_FAILED(result)) {
    3388                 :     printf("ERROR: GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
    3389               0 :            result);
    3390               0 :     return result;
    3391                 :   }
    3392                 : 
    3393               2 :   if (numitems != 1) {
    3394                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3395               0 :            numitems, result);
    3396               0 :     return NS_ERROR_FAILURE;
    3397                 :   }
    3398                 : 
    3399               2 :   passed("Test effect of unbalanced EndBatch() on undo and redo stacks");
    3400                 : 
    3401                 :   /*******************************************************************
    3402                 :    *
    3403                 :    * Make sure that an empty batch is not added to the undo stack
    3404                 :    * when it is closed, and that it does not affect the undo and redo
    3405                 :    * stacks.
    3406                 :    *
    3407                 :    *******************************************************************/
    3408                 : 
    3409               2 :   result = mgr->BeginBatch();
    3410                 : 
    3411               2 :   if (NS_FAILED(result)) {
    3412               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3413               0 :     return result;
    3414                 :   }
    3415                 : 
    3416               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3417                 : 
    3418               2 :   if (NS_FAILED(result)) {
    3419                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3420               0 :            result);
    3421               0 :     return result;
    3422                 :   }
    3423                 : 
    3424               2 :   if (numitems != 1) {
    3425                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3426               0 :            numitems, result);
    3427               0 :     return NS_ERROR_FAILURE;
    3428                 :   }
    3429                 : 
    3430               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3431                 : 
    3432               2 :   if (NS_FAILED(result)) {
    3433                 :     printf("ERROR: GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
    3434               0 :            result);
    3435               0 :     return result;
    3436                 :   }
    3437                 : 
    3438               2 :   if (numitems != 1) {
    3439                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3440               0 :            numitems, result);
    3441               0 :     return NS_ERROR_FAILURE;
    3442                 :   }
    3443                 : 
    3444               2 :   result = mgr->EndBatch();
    3445                 : 
    3446               2 :   if (NS_FAILED(result)) {
    3447               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3448               0 :     return result;
    3449                 :   }
    3450                 : 
    3451               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3452                 : 
    3453               2 :   if (NS_FAILED(result)) {
    3454                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3455               0 :            result);
    3456               0 :     return result;
    3457                 :   }
    3458                 : 
    3459               2 :   if (numitems != 1) {
    3460                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3461               0 :            numitems, result);
    3462               0 :     return NS_ERROR_FAILURE;
    3463                 :   }
    3464                 : 
    3465               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3466                 : 
    3467               2 :   if (NS_FAILED(result)) {
    3468                 :     printf("ERROR: GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
    3469               0 :            result);
    3470               0 :     return result;
    3471                 :   }
    3472                 : 
    3473               2 :   if (numitems != 1) {
    3474                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3475               0 :            numitems, result);
    3476               0 :     return NS_ERROR_FAILURE;
    3477                 :   }
    3478                 : 
    3479               2 :   passed("Test effect of empty batch on undo and redo stacks");
    3480                 : 
    3481                 :   /*******************************************************************
    3482                 :    *
    3483                 :    * Execute a new transaction. The redo stack should get pruned!
    3484                 :    *
    3485                 :    *******************************************************************/
    3486                 : 
    3487               2 :   result = mgr->BeginBatch();
    3488                 : 
    3489               2 :   if (NS_FAILED(result)) {
    3490               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3491               0 :     return result;
    3492                 :   }
    3493                 : 
    3494              42 :   for (i = 1; i <= 20; i++) {
    3495              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    3496                 : 
    3497              40 :     if (!tximpl) {
    3498               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    3499               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3500                 :     }
    3501                 : 
    3502              40 :     tx = 0;
    3503              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3504              40 :     if (NS_FAILED(result)) {
    3505                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    3506               0 :              i, result);
    3507               0 :       return result;
    3508                 :     }
    3509                 : 
    3510              40 :     result = mgr->DoTransaction(tx);
    3511              40 :     if (NS_FAILED(result)) {
    3512               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    3513               0 :       return result;
    3514                 :     }
    3515                 : 
    3516              40 :     tx->Release();
    3517                 :   }
    3518                 : 
    3519               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3520                 : 
    3521               2 :   if (NS_FAILED(result)) {
    3522                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3523               0 :            result);
    3524               0 :     return result;
    3525                 :   }
    3526                 : 
    3527               2 :   if (numitems != 1) {
    3528                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3529               0 :            numitems, result);
    3530               0 :     return NS_ERROR_FAILURE;
    3531                 :   }
    3532                 : 
    3533               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3534                 : 
    3535               2 :   if (NS_FAILED(result)) {
    3536                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
    3537               0 :            result);
    3538               0 :     return result;
    3539                 :   }
    3540                 : 
    3541               2 :   if (numitems != 1) {
    3542                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3543               0 :            numitems, result);
    3544               0 :     return NS_ERROR_FAILURE;
    3545                 :   }
    3546                 : 
    3547               2 :   result = mgr->EndBatch();
    3548                 : 
    3549               2 :   if (NS_FAILED(result)) {
    3550               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3551               0 :     return result;
    3552                 :   }
    3553                 : 
    3554               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3555                 : 
    3556               2 :   if (NS_FAILED(result)) {
    3557                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
    3558               0 :            result);
    3559               0 :     return result;
    3560                 :   }
    3561                 : 
    3562               2 :   if (numitems != 2) {
    3563                 :     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
    3564               0 :            numitems, result);
    3565               0 :     return NS_ERROR_FAILURE;
    3566                 :   }
    3567                 : 
    3568               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3569                 : 
    3570               2 :   if (NS_FAILED(result)) {
    3571                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    3572               0 :            result);
    3573               0 :     return result;
    3574                 :   }
    3575                 : 
    3576               2 :   if (numitems != 0) {
    3577                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    3578               0 :            numitems, result);
    3579               0 :     return NS_ERROR_FAILURE;
    3580                 :   }
    3581                 : 
    3582               2 :   passed("Check if new batched transactions prune the redo stack");
    3583                 : 
    3584                 :   /*******************************************************************
    3585                 :    *
    3586                 :    * Call undo.
    3587                 :    *
    3588                 :    *******************************************************************/
    3589                 : 
    3590                 :   // Move a transaction over to the redo stack, so that we have one
    3591                 :   // transaction on the undo stack, and one on the redo stack!
    3592                 : 
    3593               2 :   result = mgr->UndoTransaction();
    3594                 : 
    3595               2 :   if (NS_FAILED(result)) {
    3596               0 :     printf("ERROR: Failed to undo transaction. (%d)\n", result);
    3597               0 :     return result;
    3598                 :   }
    3599                 : 
    3600               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3601                 : 
    3602               2 :   if (NS_FAILED(result)) {
    3603                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3604               0 :            result);
    3605               0 :     return result;
    3606                 :   }
    3607                 : 
    3608               2 :   if (numitems != 1) {
    3609                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3610               0 :            numitems, result);
    3611               0 :     return NS_ERROR_FAILURE;
    3612                 :   }
    3613                 : 
    3614               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3615                 : 
    3616               2 :   if (NS_FAILED(result)) {
    3617                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
    3618               0 :            result);
    3619               0 :     return result;
    3620                 :   }
    3621                 : 
    3622               2 :   if (numitems != 1) {
    3623                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3624               0 :            numitems, result);
    3625               0 :     return NS_ERROR_FAILURE;
    3626                 :   }
    3627                 : 
    3628               2 :   passed("Call undo");
    3629                 : 
    3630                 :   /*******************************************************************
    3631                 :    *
    3632                 :    * Test transaction DoTransaction() error:
    3633                 :    *
    3634                 :    *******************************************************************/
    3635                 : 
    3636               2 :   tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
    3637                 : 
    3638               2 :   if (!tximpl) {
    3639               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3640               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3641                 :   }
    3642                 : 
    3643               2 :   tx     = 0;
    3644                 : 
    3645               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3646                 : 
    3647               2 :   if (NS_FAILED(result)) {
    3648               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3649               0 :     return result;
    3650                 :   }
    3651                 : 
    3652               2 :   u1 = u2 = r1 = r2 = 0;
    3653                 : 
    3654               2 :   result = mgr->PeekUndoStack(&u1);
    3655                 : 
    3656               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    3657                 : 
    3658               2 :   if (NS_FAILED(result)) {
    3659               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    3660               0 :     return result;
    3661                 :   }
    3662                 : 
    3663               2 :   result = mgr->PeekRedoStack(&r1);
    3664                 : 
    3665               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    3666                 : 
    3667               2 :   if (NS_FAILED(result)) {
    3668               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    3669               0 :     return result;
    3670                 :   }
    3671                 : 
    3672               2 :   result = mgr->BeginBatch();
    3673                 : 
    3674               2 :   if (NS_FAILED(result)) {
    3675               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3676               0 :     return result;
    3677                 :   }
    3678                 : 
    3679               2 :   result = mgr->DoTransaction(tx);
    3680                 : 
    3681               2 :   if (result != NS_ERROR_FAILURE) {
    3682               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    3683               0 :     return result;
    3684                 :   }
    3685                 : 
    3686               2 :   tx->Release();
    3687                 : 
    3688               2 :   result = mgr->EndBatch();
    3689                 : 
    3690               2 :   if (NS_FAILED(result)) {
    3691               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3692               0 :     return result;
    3693                 :   }
    3694                 : 
    3695               2 :   result = mgr->PeekUndoStack(&u2);
    3696                 : 
    3697               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    3698                 : 
    3699               2 :   if (NS_FAILED(result)) {
    3700               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    3701               0 :     return result;
    3702                 :   }
    3703                 : 
    3704               2 :   if (u1 != u2) {
    3705               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    3706               0 :     return NS_ERROR_FAILURE;
    3707                 :   }
    3708                 : 
    3709               2 :   result = mgr->PeekRedoStack(&r2);
    3710                 : 
    3711               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    3712                 : 
    3713               2 :   if (NS_FAILED(result)) {
    3714               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    3715               0 :     return result;
    3716                 :   }
    3717                 : 
    3718               2 :   if (r1 != r2) {
    3719               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    3720               0 :     return NS_ERROR_FAILURE;
    3721                 :   }
    3722                 : 
    3723               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3724                 : 
    3725               2 :   if (NS_FAILED(result)) {
    3726                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
    3727               0 :            result);
    3728               0 :     return result;
    3729                 :   }
    3730                 : 
    3731               2 :   if (numitems != 1) {
    3732                 :     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
    3733               0 :            numitems, result);
    3734               0 :     return NS_ERROR_FAILURE;
    3735                 :   }
    3736                 : 
    3737               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3738                 : 
    3739               2 :   if (NS_FAILED(result)) {
    3740                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
    3741               0 :            result);
    3742               0 :     return result;
    3743                 :   }
    3744                 : 
    3745               2 :   if (numitems != 1) {
    3746                 :     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
    3747               0 :            numitems, result);
    3748               0 :     return NS_ERROR_FAILURE;
    3749                 :   }
    3750                 : 
    3751               2 :   passed("Test transaction DoTransaction() error");
    3752                 : 
    3753                 :   /*******************************************************************
    3754                 :    *
    3755                 :    * Test transaction UndoTransaction() error:
    3756                 :    *
    3757                 :    *******************************************************************/
    3758                 : 
    3759               2 :   tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
    3760                 : 
    3761               2 :   if (!tximpl) {
    3762               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3763               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3764                 :   }
    3765                 : 
    3766               2 :   tx     = 0;
    3767                 : 
    3768               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3769                 : 
    3770               2 :   if (NS_FAILED(result)) {
    3771               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3772               0 :     return result;
    3773                 :   }
    3774                 : 
    3775               2 :   result = mgr->BeginBatch();
    3776                 : 
    3777               2 :   if (NS_FAILED(result)) {
    3778               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3779               0 :     return result;
    3780                 :   }
    3781                 : 
    3782               2 :   result = mgr->DoTransaction(tx);
    3783                 : 
    3784               2 :   if (NS_FAILED(result)) {
    3785               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    3786               0 :     return result;
    3787                 :   }
    3788                 : 
    3789               2 :   tx->Release();
    3790                 : 
    3791               2 :   result = mgr->EndBatch();
    3792                 : 
    3793               2 :   if (NS_FAILED(result)) {
    3794               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3795               0 :     return result;
    3796                 :   }
    3797                 : 
    3798               2 :   u1 = u2 = r1 = r2 = 0;
    3799                 : 
    3800               2 :   result = mgr->PeekUndoStack(&u1);
    3801                 : 
    3802               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    3803                 : 
    3804               2 :   if (NS_FAILED(result)) {
    3805               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    3806               0 :     return result;
    3807                 :   }
    3808                 : 
    3809               2 :   result = mgr->PeekRedoStack(&r1);
    3810                 : 
    3811               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    3812                 : 
    3813               2 :   if (NS_FAILED(result)) {
    3814               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    3815               0 :     return result;
    3816                 :   }
    3817                 : 
    3818               2 :   result = mgr->UndoTransaction();
    3819                 : 
    3820               2 :   if (result != NS_ERROR_FAILURE) {
    3821               0 :     printf("ERROR: UndoTransaction() returned unexpected error. (%d)\n", result);
    3822               0 :     return result;
    3823                 :   }
    3824                 : 
    3825               2 :   result = mgr->PeekUndoStack(&u2);
    3826                 : 
    3827               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    3828                 : 
    3829               2 :   if (NS_FAILED(result)) {
    3830               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    3831               0 :     return result;
    3832                 :   }
    3833                 : 
    3834               2 :   if (u1 != u2) {
    3835               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    3836               0 :     return NS_ERROR_FAILURE;
    3837                 :   }
    3838                 : 
    3839               2 :   result = mgr->PeekRedoStack(&r2);
    3840                 : 
    3841               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    3842                 : 
    3843               2 :   if (NS_FAILED(result)) {
    3844               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    3845               0 :     return result;
    3846                 :   }
    3847                 : 
    3848               2 :   if (r1 != r2) {
    3849               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    3850               0 :     return NS_ERROR_FAILURE;
    3851                 :   }
    3852                 : 
    3853               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    3854                 : 
    3855               2 :   if (NS_FAILED(result)) {
    3856                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
    3857               0 :            result);
    3858               0 :     return result;
    3859                 :   }
    3860                 : 
    3861               2 :   if (numitems != 2) {
    3862                 :     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
    3863               0 :            numitems, result);
    3864               0 :     return NS_ERROR_FAILURE;
    3865                 :   }
    3866                 : 
    3867               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    3868                 : 
    3869               2 :   if (NS_FAILED(result)) {
    3870                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
    3871               0 :            result);
    3872               0 :     return result;
    3873                 :   }
    3874                 : 
    3875               2 :   if (numitems != 0) {
    3876                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    3877               0 :            numitems, result);
    3878               0 :     return NS_ERROR_FAILURE;
    3879                 :   }
    3880                 : 
    3881               2 :   passed("Test transaction UndoTransaction() error");
    3882                 : 
    3883                 :   /*******************************************************************
    3884                 :    *
    3885                 :    * Test transaction RedoTransaction() error:
    3886                 :    *
    3887                 :    *******************************************************************/
    3888                 : 
    3889               2 :   tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
    3890                 : 
    3891               2 :   if (!tximpl) {
    3892               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3893               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3894                 :   }
    3895                 : 
    3896               2 :   tx     = 0;
    3897                 : 
    3898               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3899                 : 
    3900               2 :   if (NS_FAILED(result)) {
    3901                 :     printf("ERROR: QueryInterface() failed for RedoErrorTransaction. (%d)\n",
    3902               0 :            result);
    3903               0 :     return result;
    3904                 :   }
    3905                 : 
    3906               2 :   result = mgr->BeginBatch();
    3907                 : 
    3908               2 :   if (NS_FAILED(result)) {
    3909               0 :     printf("ERROR: BeginBatch() failed. (%d)\n", result);
    3910               0 :     return result;
    3911                 :   }
    3912                 : 
    3913               2 :   result = mgr->DoTransaction(tx);
    3914                 : 
    3915               2 :   if (NS_FAILED(result)) {
    3916               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    3917               0 :     return result;
    3918                 :   }
    3919                 : 
    3920               2 :   tx->Release();
    3921                 : 
    3922               2 :   result = mgr->EndBatch();
    3923                 : 
    3924               2 :   if (NS_FAILED(result)) {
    3925               0 :     printf("ERROR: EndBatch() failed. (%d)\n", result);
    3926               0 :     return result;
    3927                 :   }
    3928                 : 
    3929                 :   //
    3930                 :   // Execute a normal transaction to be used in a later test:
    3931                 :   //
    3932                 : 
    3933               2 :   tximpl = factory->create(mgr, NONE_FLAG);
    3934                 : 
    3935               2 :   if (!tximpl) {
    3936               0 :     printf("ERROR: Failed to allocate transaction.\n");
    3937               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3938                 :   }
    3939                 : 
    3940               2 :   tx     = 0;
    3941                 : 
    3942               2 :   result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    3943                 : 
    3944               2 :   if (NS_FAILED(result)) {
    3945               0 :     printf("ERROR: QueryInterface() failed for transaction. (%d)\n", result);
    3946               0 :     return result;
    3947                 :   }
    3948                 : 
    3949               2 :   result = mgr->DoTransaction(tx);
    3950                 : 
    3951               2 :   if (NS_FAILED(result)) {
    3952               0 :     printf("ERROR: DoTransaction() returned unexpected error. (%d)\n", result);
    3953               0 :     return result;
    3954                 :   }
    3955                 : 
    3956               2 :   tx->Release();
    3957                 : 
    3958                 :   //
    3959                 :   // Undo the 2 transactions just executed.
    3960                 :   //
    3961                 : 
    3962               6 :   for (i = 1; i <= 2; ++i) {
    3963               4 :     result = mgr->UndoTransaction();
    3964               4 :     if (NS_FAILED(result)) {
    3965               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    3966               0 :       return result;
    3967                 :     }
    3968                 :   }
    3969                 : 
    3970                 :   //
    3971                 :   // The RedoErrorTransaction should now be at the top of the redo stack!
    3972                 :   //
    3973                 : 
    3974               2 :   u1 = u2 = r1 = r2 = 0;
    3975                 : 
    3976               2 :   result = mgr->PeekUndoStack(&u1);
    3977                 : 
    3978               2 :   TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
    3979                 : 
    3980               2 :   if (NS_FAILED(result)) {
    3981               0 :     printf("ERROR: Initial PeekUndoStack() failed. (%d)\n", result);
    3982               0 :     return result;
    3983                 :   }
    3984                 : 
    3985               2 :   result = mgr->PeekRedoStack(&r1);
    3986                 : 
    3987               2 :   TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
    3988                 : 
    3989               2 :   if (NS_FAILED(result)) {
    3990               0 :     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
    3991               0 :     return result;
    3992                 :   }
    3993                 : 
    3994               2 :   result = mgr->RedoTransaction();
    3995                 : 
    3996               2 :   if (result != NS_ERROR_FAILURE) {
    3997               0 :     printf("ERROR: RedoTransaction() returned unexpected error. (%d)\n", result);
    3998               0 :     return result;
    3999                 :   }
    4000                 : 
    4001               2 :   result = mgr->PeekUndoStack(&u2);
    4002                 : 
    4003               2 :   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
    4004                 : 
    4005               2 :   if (NS_FAILED(result)) {
    4006               0 :     printf("ERROR: Second PeekUndoStack() failed. (%d)\n", result);
    4007               0 :     return result;
    4008                 :   }
    4009                 : 
    4010               2 :   if (u1 != u2) {
    4011               0 :     printf("ERROR: Top of undo stack changed. (%d)\n", result);
    4012               0 :     return NS_ERROR_FAILURE;
    4013                 :   }
    4014                 : 
    4015               2 :   result = mgr->PeekRedoStack(&r2);
    4016                 : 
    4017               2 :   TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
    4018                 : 
    4019               2 :   if (NS_FAILED(result)) {
    4020               0 :     printf("ERROR: Second PeekRedoStack() failed. (%d)\n", result);
    4021               0 :     return result;
    4022                 :   }
    4023                 : 
    4024               2 :   if (r1 != r2) {
    4025               0 :     printf("ERROR: Top of redo stack changed. (%d)\n", result);
    4026               0 :     return NS_ERROR_FAILURE;
    4027                 :   }
    4028                 : 
    4029               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    4030                 : 
    4031               2 :   if (NS_FAILED(result)) {
    4032                 :     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
    4033               0 :            result);
    4034               0 :     return result;
    4035                 :   }
    4036                 : 
    4037               2 :   if (numitems != 2) {
    4038                 :     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
    4039               0 :            numitems, result);
    4040               0 :     return NS_ERROR_FAILURE;
    4041                 :   }
    4042                 : 
    4043               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    4044                 : 
    4045               2 :   if (NS_FAILED(result)) {
    4046                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
    4047               0 :            result);
    4048               0 :     return result;
    4049                 :   }
    4050                 : 
    4051               2 :   if (numitems != 2) {
    4052                 :     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
    4053               0 :            numitems, result);
    4054               0 :     return NS_ERROR_FAILURE;
    4055                 :   }
    4056                 : 
    4057               2 :   passed("Test transaction RedoTransaction() error");
    4058                 : 
    4059                 :   /*******************************************************************
    4060                 :    *
    4061                 :    * Make sure that setting the transaction manager's max transaction
    4062                 :    * count to zero, clears both the undo and redo stacks, and executes
    4063                 :    * all new commands without pushing them on the undo stack!
    4064                 :    *
    4065                 :    *******************************************************************/
    4066                 : 
    4067               2 :   result = mgr->SetMaxTransactionCount(0);
    4068                 : 
    4069               2 :   if (NS_FAILED(result)) {
    4070               0 :     printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
    4071               0 :     return result;
    4072                 :   }
    4073                 : 
    4074               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    4075                 : 
    4076               2 :   if (NS_FAILED(result)) {
    4077                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    4078               0 :            result);
    4079               0 :     return result;
    4080                 :   }
    4081                 : 
    4082               2 :   if (numitems != 0) {
    4083                 :     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    4084               0 :            numitems, result);
    4085               0 :     return NS_ERROR_FAILURE;
    4086                 :   }
    4087                 : 
    4088               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    4089                 : 
    4090               2 :   if (NS_FAILED(result)) {
    4091                 :     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    4092               0 :            result);
    4093               0 :     return result;
    4094                 :   }
    4095                 : 
    4096               2 :   if (numitems != 0) {
    4097                 :     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    4098               0 :            numitems, result);
    4099               0 :     return NS_ERROR_FAILURE;
    4100                 :   }
    4101                 : 
    4102              42 :   for (i = 1; i <= 20; i++) {
    4103              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    4104                 : 
    4105              40 :     if (!tximpl) {
    4106               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    4107               0 :       return NS_ERROR_OUT_OF_MEMORY;
    4108                 :     }
    4109                 : 
    4110              40 :     tx = 0;
    4111              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    4112              40 :     if (NS_FAILED(result)) {
    4113                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    4114               0 :              i, result);
    4115               0 :       return result;
    4116                 :     }
    4117                 : 
    4118              40 :     result = mgr->BeginBatch();
    4119                 : 
    4120              40 :     if (NS_FAILED(result)) {
    4121               0 :       printf("ERROR: BeginBatch() failed. (%d)\n", result);
    4122               0 :       return result;
    4123                 :     }
    4124                 : 
    4125              40 :     result = mgr->DoTransaction(tx);
    4126              40 :     if (NS_FAILED(result)) {
    4127               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    4128               0 :       return result;
    4129                 :     }
    4130                 : 
    4131              40 :     tx->Release();
    4132                 : 
    4133              40 :     result = mgr->EndBatch();
    4134                 : 
    4135              40 :     if (NS_FAILED(result)) {
    4136               0 :       printf("ERROR: EndBatch() failed. (%d)\n", result);
    4137               0 :       return result;
    4138                 :     }
    4139                 : 
    4140              40 :     result = mgr->GetNumberOfUndoItems(&numitems);
    4141                 : 
    4142              40 :     if (NS_FAILED(result)) {
    4143                 :       printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
    4144               0 :              result);
    4145               0 :       return result;
    4146                 :     }
    4147                 : 
    4148              40 :     if (numitems != 0) {
    4149                 :       printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
    4150               0 :              numitems, result);
    4151               0 :       return NS_ERROR_FAILURE;
    4152                 :     }
    4153                 : 
    4154              40 :     result = mgr->GetNumberOfRedoItems(&numitems);
    4155                 : 
    4156              40 :     if (NS_FAILED(result)) {
    4157                 :       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    4158               0 :              result);
    4159               0 :       return result;
    4160                 :     }
    4161                 : 
    4162              40 :     if (numitems != 0) {
    4163                 :       printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    4164               0 :              numitems, result);
    4165               0 :       return NS_ERROR_FAILURE;
    4166                 :     }
    4167                 :   }
    4168                 : 
    4169               2 :   passed("Test max transaction count of zero");
    4170                 : 
    4171                 :   /*******************************************************************
    4172                 :    *
    4173                 :    * Release the transaction manager. Any transactions on the undo
    4174                 :    * and redo stack should automatically be released:
    4175                 :    *
    4176                 :    *******************************************************************/
    4177                 : 
    4178               2 :   result = mgr->SetMaxTransactionCount(-1);
    4179                 : 
    4180               2 :   if (NS_FAILED(result)) {
    4181               0 :     printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
    4182               0 :     return result;
    4183                 :   }
    4184                 : 
    4185                 :   // Push 20 transactions on the undo stack:
    4186                 : 
    4187              42 :   for (i = 1; i <= 20; i++) {
    4188              40 :     tximpl = factory->create(mgr, NONE_FLAG);
    4189                 : 
    4190              40 :     if (!tximpl) {
    4191               0 :       printf("ERROR: Failed to allocate transaction %d.\n", i);
    4192               0 :       return NS_ERROR_OUT_OF_MEMORY;
    4193                 :     }
    4194                 : 
    4195              40 :     tx = 0;
    4196              40 :     result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    4197              40 :     if (NS_FAILED(result)) {
    4198                 :       printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
    4199               0 :              i, result);
    4200               0 :       return result;
    4201                 :     }
    4202                 : 
    4203              40 :     result = mgr->BeginBatch();
    4204                 : 
    4205              40 :     if (NS_FAILED(result)) {
    4206               0 :       printf("ERROR: BeginBatch() failed. (%d)\n", result);
    4207               0 :       return result;
    4208                 :     }
    4209                 : 
    4210              40 :     result = mgr->DoTransaction(tx);
    4211              40 :     if (NS_FAILED(result)) {
    4212               0 :       printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
    4213               0 :       return result;
    4214                 :     }
    4215                 : 
    4216              40 :     tx->Release();
    4217                 : 
    4218              40 :     result = mgr->EndBatch();
    4219                 : 
    4220              40 :     if (NS_FAILED(result)) {
    4221               0 :       printf("ERROR: EndBatch() failed. (%d)\n", result);
    4222               0 :       return result;
    4223                 :     }
    4224                 : 
    4225              40 :     result = mgr->GetNumberOfUndoItems(&numitems);
    4226                 : 
    4227              40 :     if (NS_FAILED(result)) {
    4228                 :       printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
    4229               0 :              i, result);
    4230               0 :       return result;
    4231                 :     }
    4232                 : 
    4233              40 :     if (numitems != i) {
    4234                 :       printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
    4235               0 :              i, numitems, result);
    4236               0 :       return NS_ERROR_FAILURE;
    4237                 :     }
    4238                 : 
    4239              40 :     result = mgr->GetNumberOfRedoItems(&numitems);
    4240                 : 
    4241              40 :     if (NS_FAILED(result)) {
    4242                 :       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
    4243               0 :              result);
    4244               0 :       return result;
    4245                 :     }
    4246                 : 
    4247              40 :     if (numitems != 0) {
    4248                 :       printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
    4249               0 :              numitems, result);
    4250               0 :       return NS_ERROR_FAILURE;
    4251                 :     }
    4252                 :   }
    4253                 : 
    4254              22 :   for (i = 1; i <= 10; i++) {
    4255                 : 
    4256              20 :     result = mgr->UndoTransaction();
    4257              20 :     if (NS_FAILED(result)) {
    4258               0 :       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
    4259               0 :       return result;
    4260                 :     }
    4261                 :   }
    4262               2 :   result = mgr->GetNumberOfUndoItems(&numitems);
    4263                 : 
    4264               2 :   if (NS_FAILED(result)) {
    4265                 :     printf("ERROR: GetNumberOfUndoItems() on empty undo stack with 10 items failed. (%d)\n",
    4266               0 :            result);
    4267               0 :     return result;
    4268                 :   }
    4269                 : 
    4270               2 :   if (numitems != 10) {
    4271                 :     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
    4272               0 :            numitems, result);
    4273               0 :     return NS_ERROR_FAILURE;
    4274                 :   }
    4275                 : 
    4276               2 :   result = mgr->GetNumberOfRedoItems(&numitems);
    4277                 : 
    4278               2 :   if (NS_FAILED(result)) {
    4279                 :     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
    4280               0 :            result);
    4281               0 :     return result;
    4282                 :   }
    4283                 : 
    4284               2 :   if (numitems != 10) {
    4285                 :     printf("ERROR: GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
    4286               0 :            numitems, result);
    4287               0 :     return NS_ERROR_FAILURE;
    4288                 :   }
    4289                 : 
    4290               2 :   result = mgr->Clear();
    4291               2 :   if (NS_FAILED(result)) {
    4292               0 :     printf("ERROR: Clear() failed. (%d)\n", result);
    4293               0 :     return result;
    4294                 :   }
    4295                 : 
    4296               2 :   passed("Release the transaction manager");
    4297                 : 
    4298                 :   /*******************************************************************
    4299                 :    *
    4300                 :    * Make sure number of transactions created matches number of
    4301                 :    * transactions destroyed!
    4302                 :    *
    4303                 :    *******************************************************************/
    4304                 : 
    4305               2 :   if (sConstructorCount != sDestructorCount) {
    4306                 :     printf("ERROR: Transaction constructor count (%d) != destructor count (%d).\n",
    4307               0 :            sConstructorCount, sDestructorCount);
    4308               0 :     return NS_ERROR_FAILURE;
    4309                 :   }
    4310                 : 
    4311               2 :   passed("Number of transactions created and destroyed match");
    4312                 :   passed("%d transactions processed during quick batch test",
    4313               2 :          sConstructorCount);
    4314                 : 
    4315               2 :   return NS_OK;
    4316                 : }
    4317                 : 
    4318                 : nsresult
    4319               1 : simple_batch_test()
    4320                 : {
    4321                 :   /*******************************************************************
    4322                 :    *
    4323                 :    * Initialize globals for test.
    4324                 :    *
    4325                 :    *******************************************************************/
    4326               1 :   reset_globals();
    4327               1 :   sDestructorOrderArr = sSimpleBatchTestDestructorOrderArr;
    4328               1 :   sDoOrderArr         = sSimpleBatchTestDoOrderArr;
    4329               1 :   sUndoOrderArr       = sSimpleBatchTestUndoOrderArr;
    4330               1 :   sRedoOrderArr       = sSimpleBatchTestRedoOrderArr;
    4331                 : 
    4332                 :   /*******************************************************************
    4333                 :    *
    4334                 :    * Run the quick batch test.
    4335                 :    *
    4336                 :    *******************************************************************/
    4337                 : 
    4338               1 :   printf("\n-----------------------------------------------------\n");
    4339               1 :   printf("- Begin Batch Transaction Test:\n");
    4340               1 :   printf("-----------------------------------------------------\n");
    4341                 : 
    4342               1 :   SimpleTransactionFactory factory;
    4343                 : 
    4344               1 :   return quick_batch_test(&factory);
    4345                 : }
    4346                 : 
    4347                 : nsresult
    4348               1 : aggregation_batch_test()
    4349                 : {
    4350                 :   /*******************************************************************
    4351                 :    *
    4352                 :    * Initialize globals for test.
    4353                 :    *
    4354                 :    *******************************************************************/
    4355                 : 
    4356               1 :   reset_globals();
    4357               1 :   sDestructorOrderArr = sAggregateBatchTestDestructorOrderArr;
    4358               1 :   sDoOrderArr         = sAggregateBatchTestDoOrderArr;
    4359               1 :   sUndoOrderArr       = sAggregateBatchTestUndoOrderArr;
    4360               1 :   sRedoOrderArr       = sAggregateBatchTestRedoOrderArr;
    4361                 : 
    4362                 :   /*******************************************************************
    4363                 :    *
    4364                 :    * Run the quick batch test.
    4365                 :    *
    4366                 :    *******************************************************************/
    4367                 : 
    4368               1 :   printf("\n-----------------------------------------------------\n");
    4369               1 :   printf("- Begin Batch Aggregate Transaction Test:\n");
    4370               1 :   printf("-----------------------------------------------------\n");
    4371                 : 
    4372               1 :   AggregateTransactionFactory factory(3, 2, BATCH_FLAG);
    4373                 : 
    4374               1 :   return quick_batch_test(&factory);
    4375                 : }
    4376                 : 
    4377                 : /**
    4378                 :  * Create 'iterations * (iterations + 1) / 2' transactions;
    4379                 :  * do/undo/redo/undo them.
    4380                 :  **/
    4381                 : nsresult
    4382               3 : stress_test(TestTransactionFactory *factory, PRInt32 iterations)
    4383                 : {
    4384               3 :   printf("Stress test of %i iterations (may take a while) ... ", iterations);
    4385               3 :   fflush(stdout);
    4386                 : 
    4387                 :   nsresult result;
    4388                 : 
    4389                 :   /*******************************************************************
    4390                 :    *
    4391                 :    * Create a transaction manager:
    4392                 :    *
    4393                 :    *******************************************************************/
    4394                 : 
    4395                 :   nsCOMPtr<nsITransactionManager> mgr =
    4396               6 :     do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
    4397               3 :   if (NS_FAILED(result) || !mgr) {
    4398               0 :     printf("ERROR: Failed to create Transaction Manager instance.\n");
    4399               0 :     return NS_ERROR_OUT_OF_MEMORY;
    4400                 :   }
    4401                 : 
    4402                 :   PRInt32 i, j;
    4403                 :   nsITransaction *tx;
    4404                 : 
    4405              33 :   for (i = 1; i <= iterations; i++) {
    4406                 :     /*******************************************************************
    4407                 :      *
    4408                 :      * Create and execute a bunch of transactions:
    4409                 :      *
    4410                 :      *******************************************************************/
    4411                 : 
    4412             195 :     for (j = 1; j <= i; j++) {
    4413             165 :       TestTransaction *tximpl = factory->create(mgr, NONE_FLAG);
    4414                 : 
    4415             165 :       if (!tximpl) {
    4416               0 :         printf("ERROR: Failed to allocate transaction %d-%d.\n", i, j);
    4417               0 :         return NS_ERROR_OUT_OF_MEMORY;
    4418                 :       }
    4419                 : 
    4420             165 :       tx = 0;
    4421             165 :       result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
    4422             165 :       if (NS_FAILED(result)) {
    4423                 :         printf("ERROR: QueryInterface() failed for transaction %d-%d. (%d)\n",
    4424               0 :                i, j, result);
    4425               0 :         return result;
    4426                 :       }
    4427                 : 
    4428             165 :       result = mgr->DoTransaction(tx);
    4429             165 :       if (NS_FAILED(result)) {
    4430                 :         printf("ERROR: Failed to execute transaction %d-%d. (%d)\n",
    4431               0 :                i, j, result);
    4432               0 :         return result;
    4433                 :       }
    4434                 : 
    4435             165 :       tx->Release();
    4436                 :     }
    4437                 : 
    4438                 :     /*******************************************************************
    4439                 :      *
    4440                 :      * Undo all the transactions:
    4441                 :      *
    4442                 :      *******************************************************************/
    4443                 : 
    4444             195 :     for (j = 1; j <= i; j++) {
    4445             165 :       result = mgr->UndoTransaction();
    4446             165 :       if (NS_FAILED(result)) {
    4447               0 :         printf("ERROR: Failed to undo transaction %d-%d. (%d)\n", i, j, result);
    4448               0 :         return result;
    4449                 :       }
    4450                 :     }
    4451                 : 
    4452                 :     /*******************************************************************
    4453                 :      *
    4454                 :      * Redo all the transactions:
    4455                 :      *
    4456                 :      *******************************************************************/
    4457                 : 
    4458             195 :     for (j = 1; j <= i; j++) {
    4459             165 :       result = mgr->RedoTransaction();
    4460             165 :       if (NS_FAILED(result)) {
    4461               0 :         printf("ERROR: Failed to redo transaction %d-%d. (%d)\n", i, j, result);
    4462               0 :         return result;
    4463                 :       }
    4464                 :     }
    4465                 : 
    4466                 :     /*******************************************************************
    4467                 :      *
    4468                 :      * Undo all the transactions again so that they all end up on
    4469                 :      * the redo stack for pruning the next time we execute a new
    4470                 :      * transaction
    4471                 :      *
    4472                 :      *******************************************************************/
    4473                 : 
    4474             195 :     for (j = 1; j <= i; j++) {
    4475             165 :       result = mgr->UndoTransaction();
    4476             165 :       if (NS_FAILED(result)) {
    4477               0 :         printf("ERROR: Failed to undo transaction %d-%d. (%d)\n", i, j, result);
    4478               0 :         return result;
    4479                 :       }
    4480                 :     }
    4481                 : 
    4482                 :     // Trivial feedback not to let the user think the test is stuck.
    4483              30 :     if (NS_UNLIKELY(j % 100 == 0))
    4484               0 :       printf("%i ", j);
    4485                 :   } // for, iterations.
    4486                 : 
    4487               3 :   printf("passed\n");
    4488                 : 
    4489               3 :   result = mgr->Clear();
    4490               3 :   if (NS_FAILED(result)) {
    4491               0 :     printf("ERROR: Clear() failed. (%d)\n", result);
    4492               0 :     return result;
    4493                 :   }
    4494                 : 
    4495               3 :   if (sConstructorCount != sDestructorCount) {
    4496                 :     printf("ERROR: Transaction constructor count (%d) != destructor count (%d).\n",
    4497               0 :            sConstructorCount, sDestructorCount);
    4498               0 :     return NS_ERROR_FAILURE;
    4499                 :   }
    4500                 : 
    4501               3 :   passed("%d transactions processed during stress test", sConstructorCount);
    4502                 : 
    4503               3 :   return NS_OK;
    4504                 : }
    4505                 : 
    4506                 : nsresult
    4507               1 : simple_stress_test()
    4508                 : {
    4509                 :   /*******************************************************************
    4510                 :    *
    4511                 :    * Initialize globals for test.
    4512                 :    *
    4513                 :    *******************************************************************/
    4514                 : 
    4515               1 :   reset_globals();
    4516                 : 
    4517                 :   /*******************************************************************
    4518                 :    *
    4519                 :    * Do the stress test:
    4520                 :    *
    4521                 :    *******************************************************************/
    4522                 : 
    4523               1 :   printf("\n-----------------------------------------------------\n");
    4524               1 :   printf("- Simple Transaction Stress Test:\n");
    4525               1 :   printf("-----------------------------------------------------\n");
    4526                 : 
    4527               1 :   SimpleTransactionFactory factory;
    4528                 : 
    4529                 :   PRInt32 iterations =
    4530                 : #ifdef DEBUG
    4531               1 :   10
    4532                 : #else
    4533                 :   //
    4534                 :   // 1500 iterations sends 1,125,750 transactions through the system!!
    4535                 :   //
    4536                 :   1500
    4537                 : #endif
    4538                 :   ;
    4539               1 :   return stress_test(&factory, iterations);
    4540                 : }
    4541                 : 
    4542                 : nsresult
    4543               1 : aggregation_stress_test()
    4544                 : {
    4545                 :   /*******************************************************************
    4546                 :    *
    4547                 :    * Initialize globals for test.
    4548                 :    *
    4549                 :    *******************************************************************/
    4550                 : 
    4551               1 :   reset_globals();
    4552                 : 
    4553                 :   /*******************************************************************
    4554                 :    *
    4555                 :    * Do the stress test:
    4556                 :    *
    4557                 :    *******************************************************************/
    4558                 : 
    4559               1 :   printf("\n-----------------------------------------------------\n");
    4560               1 :   printf("- Aggregate Transaction Stress Test:\n");
    4561               1 :   printf("-----------------------------------------------------\n");
    4562                 : 
    4563               1 :   AggregateTransactionFactory factory(3, 4);
    4564                 : 
    4565                 :   PRInt32 iterations =
    4566                 : #ifdef DEBUG
    4567               1 :   10
    4568                 : #else
    4569                 :   //
    4570                 :   // 500 iterations sends 2,630,250 transactions through the system!!
    4571                 :   //
    4572                 :   500
    4573                 : #endif
    4574                 :   ;
    4575               1 :   return stress_test(&factory, iterations);
    4576                 : }
    4577                 : 
    4578                 : nsresult
    4579               1 : aggregation_batch_stress_test()
    4580                 : {
    4581                 :   /*******************************************************************
    4582                 :    *
    4583                 :    * Initialize globals for test.
    4584                 :    *
    4585                 :    *******************************************************************/
    4586                 : 
    4587               1 :   reset_globals();
    4588                 : 
    4589                 :   /*******************************************************************
    4590                 :    *
    4591                 :    * Do the stress test:
    4592                 :    *
    4593                 :    *******************************************************************/
    4594                 : 
    4595               1 :   printf("\n-----------------------------------------------------\n");
    4596               1 :   printf("- Aggregate Batch Transaction Stress Test:\n");
    4597               1 :   printf("-----------------------------------------------------\n");
    4598                 : 
    4599               1 :   AggregateTransactionFactory factory(3, 4, BATCH_FLAG);
    4600                 : 
    4601                 :   PRInt32 iterations =
    4602                 : #ifdef DEBUG
    4603               1 :   10
    4604                 : #else
    4605                 :   //
    4606                 :   // 500 iterations sends 2,630,250 transactions through the system!!
    4607                 :   //
    4608                 :   500
    4609                 : #endif
    4610                 :   ;
    4611               1 :   return stress_test(&factory, iterations);
    4612                 : }
    4613                 : 
    4614                 : int
    4615               1 : main (int argc, char *argv[])
    4616                 : {
    4617               2 :   ScopedXPCOM xpcom("nsITransactionManager");
    4618               1 :   if (xpcom.failed())
    4619               0 :     return 1;
    4620                 : 
    4621                 :   nsresult result;
    4622                 : 
    4623                 :   //
    4624                 :   // quick_test() part:
    4625                 :   //
    4626                 : 
    4627               1 :   result = simple_test();
    4628               1 :   NS_ENSURE_SUCCESS(result, result);
    4629                 : 
    4630               1 :   result = aggregation_test();
    4631               1 :   NS_ENSURE_SUCCESS(result, result);
    4632                 : 
    4633                 :   //
    4634                 :   // quick_batch_test() part:
    4635                 :   //
    4636                 : 
    4637               1 :   result = simple_batch_test();
    4638               1 :   NS_ENSURE_SUCCESS(result, result);
    4639                 : 
    4640               1 :   result = aggregation_batch_test();
    4641               1 :   NS_ENSURE_SUCCESS(result, result);
    4642                 : 
    4643                 :   //
    4644                 :   // stress_test() part:
    4645                 :   //
    4646                 : 
    4647               1 :   result = simple_stress_test();
    4648               1 :   NS_ENSURE_SUCCESS(result, result);
    4649                 : 
    4650               1 :   result = aggregation_stress_test();
    4651               1 :   NS_ENSURE_SUCCESS(result, result);
    4652                 : 
    4653               1 :   result = aggregation_batch_stress_test();
    4654               1 :   NS_ENSURE_SUCCESS(result, result);
    4655                 : 
    4656                 : 
    4657               1 :   return NS_OK;
    4658                 : }

Generated by: LCOV version 1.7