Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "TestHarness.h"
8 #include "nsITransactionManager.h"
9 #include "nsComponentManagerUtils.h"
10 #include "mozilla/Likely.h"
12 static int32_t sConstructorCount = 0;
13 static int32_t sDestructorCount = 0;
14 static int32_t *sDestructorOrderArr = 0;
15 static int32_t sDoCount = 0;
16 static int32_t *sDoOrderArr = 0;
17 static int32_t sUndoCount = 0;
18 static int32_t *sUndoOrderArr = 0;
19 static int32_t sRedoCount = 0;
20 static int32_t *sRedoOrderArr = 0;
22 // #define ENABLE_DEBUG_PRINTFS 1
24 int32_t sSimpleTestDestructorOrderArr[] = {
25 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
26 16, 17, 18, 19, 20, 21, 1, 22, 23, 24, 25, 26, 27, 28,
27 29, 30, 31, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
28 53, 54, 55, 56, 57, 58, 59, 60, 61, 41, 40, 62, 39, 38,
29 37, 36, 35, 34, 33, 32, 68, 63, 64, 65, 66, 67, 69, 71,
30 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
31 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
32 99, 100, 101, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 131,
33 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117,
34 116, 115, 114, 113, 112 };
36 int32_t sSimpleTestDoOrderArr[] = {
37 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
38 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
39 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
40 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
41 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
42 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
43 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
44 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
45 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
46 127, 128, 129, 130, 131 };
48 int32_t sSimpleTestUndoOrderArr[] = {
49 41, 40, 39, 38, 62, 39, 38, 37, 69, 71, 70, 111, 110, 109,
50 108, 107, 106, 105, 104, 103, 102, 131, 130, 129, 128, 127, 126, 125,
51 124, 123, 122 };
53 static int32_t sSimpleTestRedoOrderArr[] = {
54 38, 39, 70 };
56 int32_t sAggregateTestDestructorOrderArr[] = {
57 14, 13, 12, 11, 10, 9, 8, 21, 20, 19, 18, 17, 16, 15,
58 28, 27, 26, 25, 24, 23, 22, 35, 34, 33, 32, 31, 30, 29,
59 42, 41, 40, 39, 38, 37, 36, 49, 48, 47, 46, 45, 44, 43,
60 56, 55, 54, 53, 52, 51, 50, 63, 62, 61, 60, 59, 58, 57,
61 70, 69, 68, 67, 66, 65, 64, 77, 76, 75, 74, 73, 72, 71,
62 84, 83, 82, 81, 80, 79, 78, 91, 90, 89, 88, 87, 86, 85,
63 98, 97, 96, 95, 94, 93, 92, 105, 104, 103, 102, 101, 100, 99,
64 112, 111, 110, 109, 108, 107, 106, 119, 118, 117, 116, 115, 114, 113,
65 126, 125, 124, 123, 122, 121, 120, 133, 132, 131, 130, 129, 128, 127,
66 140, 139, 138, 137, 136, 135, 134, 147, 146, 145, 144, 143, 142, 141,
67 7, 6, 5, 4, 3, 2, 1, 154, 153, 152, 151, 150, 149, 148,
68 161, 160, 159, 158, 157, 156, 155, 168, 167, 166, 165, 164, 163, 162,
69 175, 174, 173, 172, 171, 170, 169, 182, 181, 180, 179, 178, 177, 176,
70 189, 188, 187, 186, 185, 184, 183, 196, 195, 194, 193, 192, 191, 190,
71 203, 202, 201, 200, 199, 198, 197, 210, 209, 208, 207, 206, 205, 204,
72 217, 216, 215, 214, 213, 212, 211, 294, 293, 292, 291, 290, 289, 288,
73 301, 300, 299, 298, 297, 296, 295, 308, 307, 306, 305, 304, 303, 302,
74 315, 314, 313, 312, 311, 310, 309, 322, 321, 320, 319, 318, 317, 316,
75 329, 328, 327, 326, 325, 324, 323, 336, 335, 334, 333, 332, 331, 330,
76 343, 342, 341, 340, 339, 338, 337, 350, 349, 348, 347, 346, 345, 344,
77 357, 356, 355, 354, 353, 352, 351, 364, 363, 362, 361, 360, 359, 358,
78 371, 370, 369, 368, 367, 366, 365, 378, 377, 376, 375, 374, 373, 372,
79 385, 384, 383, 382, 381, 380, 379, 392, 391, 390, 389, 388, 387, 386,
80 399, 398, 397, 396, 395, 394, 393, 406, 405, 404, 403, 402, 401, 400,
81 413, 412, 411, 410, 409, 408, 407, 420, 419, 418, 417, 416, 415, 414,
82 427, 426, 425, 424, 423, 422, 421, 287, 286, 285, 284, 283, 282, 281,
83 280, 279, 278, 277, 276, 275, 274, 434, 433, 432, 431, 430, 429, 428,
84 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260,
85 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246,
86 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232,
87 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218,
88 472, 471, 470, 441, 440, 439, 438, 437, 436, 435, 448, 447, 446, 445,
89 444, 443, 442, 455, 454, 453, 452, 451, 450, 449, 462, 461, 460, 459,
90 458, 457, 456, 469, 468, 467, 466, 465, 464, 463, 479, 478, 477, 476,
91 475, 474, 473, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 483,
92 482, 481, 480, 496, 497, 495, 499, 500, 498, 494, 503, 504, 502, 506,
93 507, 505, 501, 510, 511, 509, 513, 514, 512, 508, 517, 518, 516, 520,
94 521, 519, 515, 524, 525, 523, 527, 528, 526, 522, 531, 532, 530, 534,
95 535, 533, 529, 538, 539, 537, 541, 542, 540, 536, 545, 546, 544, 548,
96 549, 547, 543, 552, 553, 551, 555, 556, 554, 550, 559, 560, 558, 562,
97 563, 561, 557, 566, 567, 565, 569, 570, 568, 564, 573, 574, 572, 576,
98 577, 575, 571, 580, 581, 579, 583, 584, 582, 578, 587, 588, 586, 590,
99 591, 589, 585, 594, 595, 593, 597, 598, 596, 592, 601, 602, 600, 604,
100 605, 603, 599, 608, 609, 607, 611, 612, 610, 606, 615, 616, 614, 618,
101 619, 617, 613, 622, 623, 621, 625, 626, 624, 620, 629, 630, 628, 632,
102 633, 631, 627, 640, 639, 638, 637, 636, 635, 634, 647, 646, 645, 644,
103 643, 642, 641, 654, 653, 652, 651, 650, 649, 648, 661, 660, 659, 658,
104 657, 656, 655, 668, 667, 666, 665, 664, 663, 662, 675, 674, 673, 672,
105 671, 670, 669, 682, 681, 680, 679, 678, 677, 676, 689, 688, 687, 686,
106 685, 684, 683, 696, 695, 694, 693, 692, 691, 690, 703, 702, 701, 700,
107 699, 698, 697, 773, 772, 771, 770, 769, 768, 767, 766, 765, 764, 763,
108 762, 761, 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, 749,
109 748, 747, 746, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735,
110 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721,
111 720, 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707,
112 706, 705, 704, 913, 912, 911, 910, 909, 908, 907, 906, 905, 904, 903,
113 902, 901, 900, 899, 898, 897, 896, 895, 894, 893, 892, 891, 890, 889,
114 888, 887, 886, 885, 884, 883, 882, 881, 880, 879, 878, 877, 876, 875,
115 874, 873, 872, 871, 870, 869, 868, 867, 866, 865, 864, 863, 862, 861,
116 860, 859, 858, 857, 856, 855, 854, 853, 852, 851, 850, 849, 848, 847,
117 846, 845, 844, 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, 833,
118 832, 831, 830, 829, 828, 827, 826, 825, 824, 823, 822, 821, 820, 819,
119 818, 817, 816, 815, 814, 813, 812, 811, 810, 809, 808, 807, 806, 805,
120 804, 803, 802, 801, 800, 799, 798, 797, 796, 795, 794, 793, 792, 791,
121 790, 789, 788, 787, 786, 785, 784, 783, 782, 781, 780, 779, 778, 777,
122 776, 775, 774 };
124 int32_t sAggregateTestDoOrderArr[] = {
125 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
126 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
127 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
128 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
129 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
130 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
131 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
132 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
133 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
134 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
135 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
136 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
137 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
138 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
139 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
140 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
141 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
142 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
143 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
144 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
145 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
146 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
147 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322,
148 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
149 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
150 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
151 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
152 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392,
153 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
154 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,
155 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
156 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448,
157 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462,
158 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476,
159 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490,
160 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504,
161 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518,
162 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
163 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546,
164 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
165 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
166 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
167 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602,
168 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616,
169 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630,
170 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,
171 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658,
172 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672,
173 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
174 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700,
175 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714,
176 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728,
177 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742,
178 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756,
179 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770,
180 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784,
181 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798,
182 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812,
183 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826,
184 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840,
185 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854,
186 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868,
187 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882,
188 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896,
189 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910,
190 911, 912, 913 };
192 int32_t sAggregateTestUndoOrderArr[] = {
193 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274,
194 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260,
195 434, 433, 432, 431, 430, 429, 428, 273, 272, 271, 270, 269, 268, 267,
196 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253,
197 479, 478, 477, 476, 475, 493, 492, 491, 490, 489, 488, 487, 486, 485,
198 484, 483, 482, 481, 480, 485, 484, 483, 482, 481, 480, 773, 772, 771,
199 770, 769, 768, 767, 766, 765, 764, 763, 762, 761, 760, 759, 758, 757,
200 756, 755, 754, 753, 752, 751, 750, 749, 748, 747, 746, 745, 744, 743,
201 742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730, 729,
202 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715,
203 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 913, 912, 911,
204 910, 909, 908, 907, 906, 905, 904, 903, 902, 901, 900, 899, 898, 897,
205 896, 895, 894, 893, 892, 891, 890, 889, 888, 887, 886, 885, 884, 883,
206 882, 881, 880, 879, 878, 877, 876, 875, 874, 873, 872, 871, 870, 869,
207 868, 867, 866, 865, 864, 863, 862, 861, 860, 859, 858, 857, 856, 855,
208 854, 853, 852, 851, 850, 849, 848, 847, 846, 845, 844 };
210 int32_t sAggregateTestRedoOrderArr[] = {
211 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
212 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486 };
214 int32_t sSimpleBatchTestDestructorOrderArr[] = {
215 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
216 35, 36, 37, 38, 39, 40, 43, 42, 41, 64, 63, 62, 61, 60,
217 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
218 45, 44, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9,
219 8, 7, 6, 5, 4, 3, 2, 1, 65, 67, 66, 68, 69, 70,
220 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
221 85, 86, 87, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97,
222 96, 95, 94, 93, 92, 91, 90, 89, 88 };
224 int32_t sSimpleBatchTestDoOrderArr[] = {
225 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
226 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
227 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
228 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
229 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
230 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
231 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
232 99, 100, 101, 102, 103, 104, 105, 106, 107 };
234 int32_t sSimpleBatchTestUndoOrderArr[] = {
235 43, 42, 41, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
236 9, 8, 7, 6, 5, 4, 3, 2, 1, 43, 42, 41, 63, 62,
237 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
238 47, 46, 45, 44, 65, 67, 66, 107, 106, 105, 104, 103, 102, 101,
239 100, 99, 98 };
241 int32_t sSimpleBatchTestRedoOrderArr[] = {
242 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
243 15, 16, 17, 18, 19, 20, 41, 42, 43, 66 };
245 int32_t sAggregateBatchTestDestructorOrderArr[] = {
246 147, 146, 145, 144, 143, 142, 141, 154, 153, 152, 151, 150, 149, 148,
247 161, 160, 159, 158, 157, 156, 155, 168, 167, 166, 165, 164, 163, 162,
248 175, 174, 173, 172, 171, 170, 169, 182, 181, 180, 179, 178, 177, 176,
249 189, 188, 187, 186, 185, 184, 183, 196, 195, 194, 193, 192, 191, 190,
250 203, 202, 201, 200, 199, 198, 197, 210, 209, 208, 207, 206, 205, 204,
251 217, 216, 215, 214, 213, 212, 211, 224, 223, 222, 221, 220, 219, 218,
252 231, 230, 229, 228, 227, 226, 225, 238, 237, 236, 235, 234, 233, 232,
253 245, 244, 243, 242, 241, 240, 239, 252, 251, 250, 249, 248, 247, 246,
254 259, 258, 257, 256, 255, 254, 253, 266, 265, 264, 263, 262, 261, 260,
255 273, 272, 271, 270, 269, 268, 267, 280, 279, 278, 277, 276, 275, 274,
256 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288,
257 287, 286, 285, 284, 283, 282, 281, 444, 443, 442, 441, 440, 439, 438,
258 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424,
259 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410,
260 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 396,
261 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 384, 383, 382,
262 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368,
263 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354,
264 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340,
265 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326,
266 325, 324, 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312,
267 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 140, 139, 138, 137,
268 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123,
269 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109,
270 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95,
271 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
272 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
273 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53,
274 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39,
275 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25,
276 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
277 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 451, 450, 449, 448,
278 447, 446, 445, 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, 455,
279 454, 453, 452, 468, 469, 467, 471, 472, 470, 466, 475, 476, 474, 478,
280 479, 477, 473, 482, 483, 481, 485, 486, 484, 480, 489, 490, 488, 492,
281 493, 491, 487, 496, 497, 495, 499, 500, 498, 494, 503, 504, 502, 506,
282 507, 505, 501, 510, 511, 509, 513, 514, 512, 508, 517, 518, 516, 520,
283 521, 519, 515, 524, 525, 523, 527, 528, 526, 522, 531, 532, 530, 534,
284 535, 533, 529, 538, 539, 537, 541, 542, 540, 536, 545, 546, 544, 548,
285 549, 547, 543, 552, 553, 551, 555, 556, 554, 550, 559, 560, 558, 562,
286 563, 561, 557, 566, 567, 565, 569, 570, 568, 564, 573, 574, 572, 576,
287 577, 575, 571, 580, 581, 579, 583, 584, 582, 578, 587, 588, 586, 590,
288 591, 589, 585, 594, 595, 593, 597, 598, 596, 592, 601, 602, 600, 604,
289 605, 603, 599, 745, 744, 743, 742, 741, 740, 739, 738, 737, 736, 735,
290 734, 733, 732, 731, 730, 729, 728, 727, 726, 725, 724, 723, 722, 721,
291 720, 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707,
292 706, 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693,
293 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679,
294 678, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, 665,
295 664, 663, 662, 661, 660, 659, 658, 657, 656, 655, 654, 653, 652, 651,
296 650, 649, 648, 647, 646, 645, 644, 643, 642, 641, 640, 639, 638, 637,
297 636, 635, 634, 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, 623,
298 622, 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, 610, 609,
299 608, 607, 606 };
301 int32_t sAggregateBatchTestDoOrderArr[] = {
302 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
303 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
304 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
305 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
306 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
307 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
308 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
309 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
310 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
311 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
312 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
313 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
314 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
315 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
316 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
317 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
318 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
319 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
320 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
321 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
322 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
323 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
324 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322,
325 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336,
326 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
327 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
328 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
329 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392,
330 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
331 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,
332 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434,
333 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448,
334 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462,
335 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476,
336 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490,
337 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504,
338 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518,
339 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
340 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546,
341 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
342 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
343 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588,
344 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602,
345 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616,
346 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630,
347 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644,
348 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658,
349 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672,
350 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
351 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700,
352 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714,
353 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728,
354 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742,
355 743, 744, 745 };
357 int32_t sAggregateBatchTestUndoOrderArr[] = {
358 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, 288,
359 287, 286, 285, 284, 283, 282, 281, 140, 139, 138, 137, 136, 135, 134,
360 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120,
361 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106,
362 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92,
363 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78,
364 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64,
365 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50,
366 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36,
367 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
368 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8,
369 7, 6, 5, 4, 3, 2, 1, 301, 300, 299, 298, 297, 296, 295,
370 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281,
371 441, 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428,
372 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414,
373 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400,
374 399, 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386,
375 385, 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, 372,
376 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358,
377 357, 356, 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, 344,
378 343, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330,
379 329, 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, 317, 316,
380 315, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302,
381 451, 450, 449, 448, 447, 465, 464, 463, 462, 461, 460, 459, 458, 457,
382 456, 455, 454, 453, 452, 457, 456, 455, 454, 453, 452, 745, 744, 743,
383 742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730, 729,
384 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715,
385 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 703, 702, 701,
386 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687,
387 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676 };
389 int32_t sAggregateBatchTestRedoOrderArr[] = {
390 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
391 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
392 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
393 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
394 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
395 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
396 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
397 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
398 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
399 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
400 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
401 295, 296, 297, 298, 299, 300, 301, 448, 449, 450, 451, 452, 453, 454,
402 455, 456, 457, 458 };
404 #define TEST_TXMGR_IF_RELEASE(tx) if (tx) tx->Release(); // Release but don't clear pointer!
406 class TestTransaction : public nsITransaction
407 {
408 public:
410 TestTransaction() {}
411 virtual ~TestTransaction() {}
413 NS_DECL_ISUPPORTS
414 };
416 NS_IMPL_ISUPPORTS(TestTransaction, nsITransaction)
418 class SimpleTransaction : public TestTransaction
419 {
420 protected:
422 #define NONE_FLAG 0
423 #define THROWS_DO_ERROR_FLAG 1
424 #define THROWS_UNDO_ERROR_FLAG 2
425 #define THROWS_REDO_ERROR_FLAG 4
426 #define MERGE_FLAG 8
427 #define TRANSIENT_FLAG 16
428 #define BATCH_FLAG 32
429 #define ALL_ERROR_FLAGS (THROWS_DO_ERROR_FLAG|THROWS_UNDO_ERROR_FLAG|THROWS_REDO_ERROR_FLAG)
431 int32_t mVal;
432 int32_t mFlags;
434 public:
436 SimpleTransaction(int32_t aFlags=NONE_FLAG)
437 : mVal(++sConstructorCount), mFlags(aFlags)
438 {}
440 virtual ~SimpleTransaction()
441 {
442 //
443 // Make sure transactions are being destroyed in the order we expect!
444 // Notice that we don't check to see if we go past the end of the array.
445 // This is done on purpose since we want to crash if the order array is out
446 // of date.
447 //
448 /* Disabled because the current cycle collector doesn't delete
449 cycle collectable objects synchronously, nor doesn't guarantee any order.
450 if (sDestructorOrderArr && mVal != sDestructorOrderArr[sDestructorCount]) {
451 fail("~SimpleTransaction expected %d got %d.\n",
452 mVal, sDestructorOrderArr[sDestructorCount]);
453 exit(-1);
454 }
455 */
457 ++sDestructorCount;
459 #ifdef ENABLE_DEBUG_PRINTFS
460 printf("\n~SimpleTransaction: %d - 0x%.8x\n", mVal, (int32_t)this);
461 #endif // ENABLE_DEBUG_PRINTFS
463 mVal = -1;
464 }
466 NS_IMETHOD DoTransaction()
467 {
468 //
469 // Make sure DoTransaction() is called in the order we expect!
470 // Notice that we don't check to see if we go past the end of the array.
471 // This is done on purpose since we want to crash if the order array is out
472 // of date.
473 //
474 if (sDoOrderArr && mVal != sDoOrderArr[sDoCount]) {
475 fail("DoTransaction expected %d got %d.\n",
476 mVal, sDoOrderArr[sDoCount]);
477 exit(-1);
478 }
480 ++sDoCount;
482 #ifdef ENABLE_DEBUG_PRINTFS
483 printf("\nSimpleTransaction.DoTransaction: %d - 0x%.8x\n", mVal, (int32_t)this);
484 #endif // ENABLE_DEBUG_PRINTFS
486 return (mFlags & THROWS_DO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
487 }
489 NS_IMETHOD UndoTransaction()
490 {
491 //
492 // Make sure UndoTransaction() is called in the order we expect!
493 // Notice that we don't check to see if we go past the end of the array.
494 // This is done on purpose since we want to crash if the order array is out
495 // of date.
496 //
497 if (sUndoOrderArr && mVal != sUndoOrderArr[sUndoCount]) {
498 fail("UndoTransaction expected %d got %d.\n",
499 mVal, sUndoOrderArr[sUndoCount]);
500 exit(-1);
501 }
503 ++sUndoCount;
505 #ifdef ENABLE_DEBUG_PRINTFS
506 printf("\nSimpleTransaction.Undo: %d - 0x%.8x\n", mVal, (int32_t)this);
507 #endif // ENABLE_DEBUG_PRINTFS
509 return (mFlags & THROWS_UNDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
510 }
512 NS_IMETHOD RedoTransaction()
513 {
514 //
515 // Make sure RedoTransaction() is called in the order we expect!
516 // Notice that we don't check to see if we go past the end of the array.
517 // This is done on purpose since we want to crash if the order array is out
518 // of date.
519 //
520 if (sRedoOrderArr && mVal != sRedoOrderArr[sRedoCount]) {
521 fail("RedoTransaction expected %d got %d.\n",
522 mVal, sRedoOrderArr[sRedoCount]);
523 exit(-1);
524 }
526 ++sRedoCount;
528 #ifdef ENABLE_DEBUG_PRINTFS
529 printf("\nSimpleTransaction.Redo: %d - 0x%.8x\n", mVal, (int32_t)this);
530 #endif // ENABLE_DEBUG_PRINTFS
532 return (mFlags & THROWS_REDO_ERROR_FLAG) ? NS_ERROR_FAILURE : NS_OK;
533 }
535 NS_IMETHOD GetIsTransient(bool *aIsTransient)
536 {
537 if (aIsTransient)
538 *aIsTransient = (mFlags & TRANSIENT_FLAG) ? true : false;
540 return NS_OK;
541 }
543 NS_IMETHOD Merge(nsITransaction *aTransaction, bool *aDidMerge)
544 {
545 if (aDidMerge)
546 *aDidMerge = (mFlags & MERGE_FLAG) ? true : false;
548 return NS_OK;
549 }
550 };
552 class AggregateTransaction : public SimpleTransaction
553 {
554 private:
556 AggregateTransaction(nsITransactionManager *aTXMgr, int32_t aLevel,
557 int32_t aNumber, int32_t aMaxLevel,
558 int32_t aNumChildrenPerNode,
559 int32_t aFlags)
560 {
561 mLevel = aLevel;
562 mNumber = aNumber;
563 mTXMgr = aTXMgr;
564 mFlags = aFlags & (~ALL_ERROR_FLAGS);
565 mErrorFlags = aFlags & ALL_ERROR_FLAGS;
566 mTXMgr = aTXMgr;
567 mMaxLevel = aMaxLevel;
568 mNumChildrenPerNode = aNumChildrenPerNode;
569 }
571 nsITransactionManager *mTXMgr;
573 int32_t mLevel;
574 int32_t mNumber;
575 int32_t mErrorFlags;
577 int32_t mMaxLevel;
578 int32_t mNumChildrenPerNode;
580 public:
582 AggregateTransaction(nsITransactionManager *aTXMgr,
583 int32_t aMaxLevel, int32_t aNumChildrenPerNode,
584 int32_t aFlags=NONE_FLAG)
585 {
586 mLevel = 1;
587 mNumber = 1;
588 mFlags = aFlags & (~ALL_ERROR_FLAGS);
589 mErrorFlags = aFlags & ALL_ERROR_FLAGS;
590 mTXMgr = aTXMgr;
591 mMaxLevel = aMaxLevel;
592 mNumChildrenPerNode = aNumChildrenPerNode;
593 }
595 virtual ~AggregateTransaction()
596 {
597 // printf("~AggregateTransaction(0x%.8x) - %3d (%3d)\n", this, mLevel, mVal);
598 }
600 NS_IMETHOD DoTransaction()
601 {
602 if (mLevel >= mMaxLevel) {
603 // Only leaf nodes can throw errors!
604 mFlags |= mErrorFlags;
605 }
607 nsresult result = SimpleTransaction::DoTransaction();
609 if (NS_FAILED(result)) {
610 // fail("QueryInterface() failed for transaction level %d. (%d)\n",
611 // mLevel, result);
612 return result;
613 }
615 if (mLevel >= mMaxLevel)
616 return NS_OK;
618 if (mFlags & BATCH_FLAG) {
619 result = mTXMgr->BeginBatch(nullptr);
620 if (NS_FAILED(result)) {
621 return result;
622 }
623 }
625 int32_t cLevel = mLevel + 1;
627 for (int i = 1; i <= mNumChildrenPerNode; i++) {
628 int32_t flags = mErrorFlags & THROWS_DO_ERROR_FLAG;
630 if ((mErrorFlags & THROWS_REDO_ERROR_FLAG) && i == mNumChildrenPerNode) {
631 // Make the rightmost leaf transaction throw the error!
632 flags = THROWS_REDO_ERROR_FLAG;
633 mErrorFlags = mErrorFlags & (~THROWS_REDO_ERROR_FLAG);
634 }
635 else if ((mErrorFlags & THROWS_UNDO_ERROR_FLAG)
636 && i == 1) {
637 // Make the leftmost leaf transaction throw the error!
638 flags = THROWS_UNDO_ERROR_FLAG;
639 mErrorFlags = mErrorFlags & (~THROWS_UNDO_ERROR_FLAG);
640 }
642 flags |= mFlags & BATCH_FLAG;
644 AggregateTransaction *tximpl =
645 new AggregateTransaction(mTXMgr, cLevel, i, mMaxLevel,
646 mNumChildrenPerNode, flags);
648 if (!tximpl) {
649 fail("Failed to allocate AggregateTransaction %d, level %d. (%d)\n",
650 i, mLevel, result);
652 if (mFlags & BATCH_FLAG)
653 mTXMgr->EndBatch(false);
655 return NS_ERROR_OUT_OF_MEMORY;
656 }
658 nsITransaction *tx = 0;
659 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
660 if (NS_FAILED(result)) {
661 fail("QueryInterface() failed for transaction %d, level %d. (%d)\n",
662 i, mLevel, result);
664 if (mFlags & BATCH_FLAG)
665 mTXMgr->EndBatch(false);
667 return result;
668 }
670 result = mTXMgr->DoTransaction(tx);
672 if (NS_FAILED(result)) {
673 // fail("Failed to execute transaction %d, level %d. (%d)\n",
674 // i, mLevel, result);
675 tx->Release();
677 if (mFlags & BATCH_FLAG)
678 mTXMgr->EndBatch(false);
680 return result;
681 }
683 tx->Release();
684 }
686 if (mFlags & BATCH_FLAG)
687 mTXMgr->EndBatch(false);
689 return result;
690 }
691 };
693 class TestTransactionFactory
694 {
695 public:
696 virtual TestTransaction *create(nsITransactionManager *txmgr, int32_t flags) = 0;
697 };
699 class SimpleTransactionFactory : public TestTransactionFactory
700 {
701 public:
703 TestTransaction *create(nsITransactionManager *txmgr, int32_t flags)
704 {
705 return (TestTransaction *)new SimpleTransaction(flags);
706 }
707 };
709 class AggregateTransactionFactory : public TestTransactionFactory
710 {
711 private:
713 int32_t mMaxLevel;
714 int32_t mNumChildrenPerNode;
715 int32_t mFixedFlags;
717 public:
719 AggregateTransactionFactory(int32_t aMaxLevel, int32_t aNumChildrenPerNode,
720 int32_t aFixedFlags=NONE_FLAG)
721 : mMaxLevel(aMaxLevel), mNumChildrenPerNode(aNumChildrenPerNode),
722 mFixedFlags(aFixedFlags)
723 {
724 }
726 virtual TestTransaction *create(nsITransactionManager *txmgr, int32_t flags)
727 {
728 return (TestTransaction *)new AggregateTransaction(txmgr, mMaxLevel,
729 mNumChildrenPerNode,
730 flags | mFixedFlags);
731 }
732 };
734 void
735 reset_globals()
736 {
737 sConstructorCount = 0;
739 sDestructorCount = 0;
740 sDestructorOrderArr = 0;
742 sDoCount = 0;
743 sDoOrderArr = 0;
745 sUndoCount = 0;
746 sUndoOrderArr = 0;
748 sRedoCount = 0;
749 sRedoOrderArr = 0;
750 }
752 /**
753 * Test behaviors in non-batch mode.
754 **/
755 nsresult
756 quick_test(TestTransactionFactory *factory)
757 {
758 nsresult result;
760 /*******************************************************************
761 *
762 * Create a transaction manager implementation:
763 *
764 *******************************************************************/
766 nsCOMPtr<nsITransactionManager> mgr =
767 do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
768 if (NS_FAILED(result) || !mgr) {
769 fail("Failed to create Transaction Manager instance.\n");
770 return NS_ERROR_OUT_OF_MEMORY;
771 }
773 passed("Create transaction manager instance");
775 /*******************************************************************
776 *
777 * Call DoTransaction() with a null transaction:
778 *
779 *******************************************************************/
781 result = mgr->DoTransaction(0);
783 if (result != NS_ERROR_NULL_POINTER) {
784 fail("DoTransaction() returned unexpected error. (%d)\n", result);
785 return result;
786 }
788 passed("Call DoTransaction() with null transaction");
790 /*******************************************************************
791 *
792 * Call UndoTransaction() with an empty undo stack:
793 *
794 *******************************************************************/
796 result = mgr->UndoTransaction();
798 if (NS_FAILED(result)) {
799 fail("Undo on empty undo stack failed. (%d)\n", result);
800 return result;
801 }
803 passed("Call UndoTransaction() with empty undo stack");
805 /*******************************************************************
806 *
807 * Call RedoTransaction() with an empty redo stack:
808 *
809 *******************************************************************/
811 result = mgr->RedoTransaction();
813 if (NS_FAILED(result)) {
814 fail("Redo on empty redo stack failed. (%d)\n", result);
815 return result;
816 }
818 passed("Call RedoTransaction() with empty redo stack");
820 /*******************************************************************
821 *
822 * Call SetMaxTransactionCount(-1) with empty undo and redo stacks:
823 *
824 *******************************************************************/
826 result = mgr->SetMaxTransactionCount(-1);
828 if (NS_FAILED(result)) {
829 fail("SetMaxTransactionCount(-1) failed. (%d)\n", result);
830 return result;
831 }
833 passed("Call SetMaxTransactionCount(-1) with empty undo and redo stacks");
835 /*******************************************************************
836 *
837 * Call SetMaxTransactionCount(0) with empty undo and redo stacks:
838 *
839 *******************************************************************/
841 result = mgr->SetMaxTransactionCount(0);
843 if (NS_FAILED(result)) {
844 fail("SetMaxTransactionCount(0) failed. (%d)\n", result);
845 return result;
846 }
848 passed("Call SetMaxTransactionCount(0) with empty undo and redo stacks");
850 /*******************************************************************
851 *
852 * Call SetMaxTransactionCount(10) with empty undo and redo stacks:
853 *
854 *******************************************************************/
856 result = mgr->SetMaxTransactionCount(10);
858 if (NS_FAILED(result)) {
859 fail("SetMaxTransactionCount(10) failed. (%d)\n", result);
860 return result;
861 }
863 passed("Call SetMaxTransactionCount(10) with empty undo and redo stacks");
865 /*******************************************************************
866 *
867 * Call Clear() with empty undo and redo stacks:
868 *
869 *******************************************************************/
871 result = mgr->Clear();
872 if (NS_FAILED(result)) {
873 fail("Clear on empty undo and redo stack failed. (%d)\n", result);
874 return result;
875 }
877 passed("Call Clear() with empty undo and redo stack");
879 int32_t numitems;
881 /*******************************************************************
882 *
883 * Call GetNumberOfUndoItems() with an empty undo stack:
884 *
885 *******************************************************************/
887 result = mgr->GetNumberOfUndoItems(&numitems);
889 if (NS_FAILED(result)) {
890 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
891 result);
892 return result;
893 }
895 if (numitems != 0) {
896 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
897 numitems, result);
898 return NS_ERROR_FAILURE;
899 }
901 passed("Call GetNumberOfUndoItems() with empty undo stack");
903 /*******************************************************************
904 *
905 * Call GetNumberOfRedoItems() with an empty redo stack:
906 *
907 *******************************************************************/
909 result = mgr->GetNumberOfRedoItems(&numitems);
911 if (NS_FAILED(result)) {
912 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
913 result);
914 return result;
915 }
917 if (numitems != 0) {
918 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
919 numitems, result);
920 return NS_ERROR_FAILURE;
921 }
923 passed("Call GetNumberOfRedoItems() with empty redo stack");
925 nsITransaction *tx;
927 /*******************************************************************
928 *
929 * Call PeekUndoStack() with an empty undo stack:
930 *
931 *******************************************************************/
933 tx = 0;
934 result = mgr->PeekUndoStack(&tx);
936 TEST_TXMGR_IF_RELEASE(tx); // Don't hold onto any references!
938 if (NS_FAILED(result)) {
939 fail("PeekUndoStack() on empty undo stack failed. (%d)\n", result);
940 return result;
941 }
943 if (tx != 0) {
944 fail("PeekUndoStack() on empty undo stack failed. (%d)\n", result);
945 return NS_ERROR_FAILURE;
946 }
948 passed("Call PeekUndoStack() with empty undo stack");
950 /*******************************************************************
951 *
952 * Call PeekRedoStack() with an empty undo stack:
953 *
954 *******************************************************************/
956 tx = 0;
957 result = mgr->PeekRedoStack(&tx);
959 TEST_TXMGR_IF_RELEASE(tx); // Don't hold onto any references!
961 if (NS_FAILED(result)) {
962 fail("PeekRedoStack() on empty redo stack failed. (%d)\n", result);
963 return result;
964 }
966 if (tx != 0) {
967 fail("PeekRedoStack() on empty redo stack failed. (%d)\n", result);
968 return NS_ERROR_FAILURE;
969 }
971 passed("Call PeekRedoStack() with empty undo stack");
973 /*******************************************************************
974 *
975 * Call AddListener() with a null listener pointer:
976 *
977 *******************************************************************/
979 result = mgr->AddListener(0);
981 if (result != NS_ERROR_NULL_POINTER) {
982 fail("AddListener() returned unexpected error. (%d)\n", result);
983 return result;
984 }
986 passed("Call AddListener() with null listener");
988 /*******************************************************************
989 *
990 * Call RemoveListener() with a null listener pointer:
991 *
992 *******************************************************************/
994 result = mgr->RemoveListener(0);
996 if (result != NS_ERROR_NULL_POINTER) {
997 fail("RemoveListener() returned unexpected error. (%d)\n", result);
998 return result;
999 }
1001 passed("Call RemoveListener() with null listener");
1003 int32_t i;
1004 TestTransaction *tximpl;
1005 nsITransaction *u1, *u2;
1006 nsITransaction *r1, *r2;
1008 /*******************************************************************
1009 *
1010 * Test coalescing by executing a transaction that can merge any
1011 * command into itself. Then execute 20 transaction. Afterwards,
1012 * we should still have the first transaction sitting on the undo
1013 * stack. Then clear the undo and redo stacks.
1014 *
1015 *******************************************************************/
1017 result = mgr->SetMaxTransactionCount(10);
1019 if (NS_FAILED(result)) {
1020 fail("SetMaxTransactionCount(10) failed. (%d)\n", result);
1021 return result;
1022 }
1025 tximpl = factory->create(mgr, MERGE_FLAG);
1027 if (!tximpl) {
1028 fail("Failed to allocate initial transaction.\n");
1029 return NS_ERROR_OUT_OF_MEMORY;
1030 }
1032 tx = 0;
1034 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1036 if (NS_FAILED(result)) {
1037 fail("QueryInterface() failed for initial transaction. (%d)\n",
1038 result);
1039 return result;
1040 }
1042 result = mgr->DoTransaction(tx);
1044 if (NS_FAILED(result)) {
1045 fail("Failed to execute initial transaction. (%d)\n", result);
1046 return result;
1047 }
1049 tx->Release();
1051 u1 = u2 = r1 = r2 = 0;
1053 result = mgr->PeekUndoStack(&u1);
1055 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
1057 if (NS_FAILED(result)) {
1058 fail("Initial PeekUndoStack() failed. (%d)\n", result);
1059 return result;
1060 }
1062 if (u1 != tx) {
1063 fail("Top of undo stack is different!. (%d)\n", result);
1064 return NS_ERROR_FAILURE;
1065 }
1067 result = mgr->PeekRedoStack(&r1);
1069 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
1071 if (NS_FAILED(result)) {
1072 fail("Initial PeekRedoStack() failed. (%d)\n", result);
1073 return result;
1074 }
1076 for (i = 1; i <= 20; i++) {
1077 tximpl = factory->create(mgr, NONE_FLAG);
1079 if (!tximpl) {
1080 fail("Failed to allocate transaction %d.\n", i);
1081 return NS_ERROR_OUT_OF_MEMORY;
1082 }
1084 tx = 0;
1085 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1086 if (NS_FAILED(result)) {
1087 fail("QueryInterface() failed for transaction %d. (%d)\n",
1088 i, result);
1089 return result;
1090 }
1092 result = mgr->DoTransaction(tx);
1093 if (NS_FAILED(result)) {
1094 fail("Failed to execute transaction %d. (%d)\n", i, result);
1095 return result;
1096 }
1098 tx->Release();
1099 }
1101 result = mgr->PeekUndoStack(&u2);
1103 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
1105 if (NS_FAILED(result)) {
1106 fail("Second PeekUndoStack() failed. (%d)\n", result);
1107 return result;
1108 }
1110 if (u1 != u2) {
1111 fail("Top of undo stack changed. (%d)\n", result);
1112 return NS_ERROR_FAILURE;
1113 }
1115 result = mgr->PeekRedoStack(&r2);
1117 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
1119 if (NS_FAILED(result)) {
1120 fail("Second PeekRedoStack() failed. (%d)\n", result);
1121 return result;
1122 }
1124 if (r1 != r2) {
1125 fail("Top of redo stack changed. (%d)\n", result);
1126 return NS_ERROR_FAILURE;
1127 }
1129 result = mgr->GetNumberOfUndoItems(&numitems);
1131 if (NS_FAILED(result)) {
1132 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
1133 result);
1134 return result;
1135 }
1137 if (numitems != 1) {
1138 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
1139 numitems, result);
1140 return NS_ERROR_FAILURE;
1141 }
1143 result = mgr->GetNumberOfRedoItems(&numitems);
1145 if (NS_FAILED(result)) {
1146 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
1147 result);
1148 return result;
1149 }
1151 if (numitems != 0) {
1152 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1153 numitems, result);
1154 return NS_ERROR_FAILURE;
1155 }
1157 result = mgr->Clear();
1158 if (NS_FAILED(result)) {
1159 fail("Clear() failed. (%d)\n", result);
1160 return result;
1161 }
1163 passed("Test coalescing of transactions");
1165 /*******************************************************************
1166 *
1167 * Execute 20 transactions. Afterwards, we should have 10
1168 * transactions on the undo stack:
1169 *
1170 *******************************************************************/
1172 for (i = 1; i <= 20; i++) {
1173 tximpl = factory->create(mgr, NONE_FLAG);
1175 if (!tximpl) {
1176 fail("Failed to allocate transaction %d.\n", i);
1177 return NS_ERROR_OUT_OF_MEMORY;
1178 }
1180 tx = 0;
1181 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1182 if (NS_FAILED(result)) {
1183 fail("QueryInterface() failed for transaction %d. (%d)\n",
1184 i, result);
1185 return result;
1186 }
1188 result = mgr->DoTransaction(tx);
1189 if (NS_FAILED(result)) {
1190 fail("Failed to execute transaction %d. (%d)\n", i, result);
1191 return result;
1192 }
1194 tx->Release();
1195 }
1197 result = mgr->GetNumberOfUndoItems(&numitems);
1199 if (NS_FAILED(result)) {
1200 fail("GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
1201 result);
1202 return result;
1203 }
1205 if (numitems != 10) {
1206 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
1207 numitems, result);
1208 return NS_ERROR_FAILURE;
1209 }
1211 result = mgr->GetNumberOfRedoItems(&numitems);
1213 if (NS_FAILED(result)) {
1214 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
1215 result);
1216 return result;
1217 }
1219 if (numitems != 0) {
1220 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1221 numitems, result);
1222 return NS_ERROR_FAILURE;
1223 }
1225 passed("Execute 20 transactions");
1227 /*******************************************************************
1228 *
1229 * Execute 20 transient transactions. Afterwards, we should still
1230 * have the same 10 transactions on the undo stack:
1231 *
1232 *******************************************************************/
1234 u1 = u2 = r1 = r2 = 0;
1236 result = mgr->PeekUndoStack(&u1);
1238 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
1240 if (NS_FAILED(result)) {
1241 fail("Initial PeekUndoStack() failed. (%d)\n", result);
1242 return result;
1243 }
1245 result = mgr->PeekRedoStack(&r1);
1247 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
1249 if (NS_FAILED(result)) {
1250 fail("Initial PeekRedoStack() failed. (%d)\n", result);
1251 return result;
1252 }
1254 for (i = 1; i <= 20; i++) {
1255 tximpl = factory->create(mgr, TRANSIENT_FLAG);
1257 if (!tximpl) {
1258 fail("Failed to allocate transaction %d.\n", i);
1259 return NS_ERROR_OUT_OF_MEMORY;
1260 }
1262 tx = 0;
1263 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1264 if (NS_FAILED(result)) {
1265 fail("QueryInterface() failed for transaction %d. (%d)\n",
1266 i, result);
1267 return result;
1268 }
1270 result = mgr->DoTransaction(tx);
1271 if (NS_FAILED(result)) {
1272 fail("Failed to execute transaction %d. (%d)\n", i, result);
1273 return result;
1274 }
1276 tx->Release();
1277 }
1279 result = mgr->PeekUndoStack(&u2);
1281 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
1283 if (NS_FAILED(result)) {
1284 fail("Second PeekUndoStack() failed. (%d)\n", result);
1285 return result;
1286 }
1288 if (u1 != u2) {
1289 fail("Top of undo stack changed. (%d)\n", result);
1290 return NS_ERROR_FAILURE;
1291 }
1293 result = mgr->PeekRedoStack(&r2);
1295 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
1297 if (NS_FAILED(result)) {
1298 fail("Second PeekRedoStack() failed. (%d)\n", result);
1299 return result;
1300 }
1302 if (r1 != r2) {
1303 fail("Top of redo stack changed. (%d)\n", result);
1304 return NS_ERROR_FAILURE;
1305 }
1307 result = mgr->GetNumberOfUndoItems(&numitems);
1309 if (NS_FAILED(result)) {
1310 fail("GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
1311 result);
1312 return result;
1313 }
1315 if (numitems != 10) {
1316 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
1317 numitems, result);
1318 return NS_ERROR_FAILURE;
1319 }
1321 result = mgr->GetNumberOfRedoItems(&numitems);
1323 if (NS_FAILED(result)) {
1324 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
1325 result);
1326 return result;
1327 }
1329 if (numitems != 0) {
1330 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1331 numitems, result);
1332 return NS_ERROR_FAILURE;
1333 }
1335 passed("Execute 20 transient transactions");
1337 /*******************************************************************
1338 *
1339 * Undo 4 transactions. Afterwards, we should have 6 transactions
1340 * on the undo stack, and 4 on the redo stack:
1341 *
1342 *******************************************************************/
1344 for (i = 1; i <= 4; i++) {
1345 result = mgr->UndoTransaction();
1346 if (NS_FAILED(result)) {
1347 fail("Failed to undo transaction %d. (%d)\n", i, result);
1348 return result;
1349 }
1350 }
1352 result = mgr->GetNumberOfUndoItems(&numitems);
1354 if (NS_FAILED(result)) {
1355 fail("GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
1356 result);
1357 return result;
1358 }
1360 if (numitems != 6) {
1361 fail("GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
1362 numitems, result);
1363 return NS_ERROR_FAILURE;
1364 }
1366 result = mgr->GetNumberOfRedoItems(&numitems);
1368 if (NS_FAILED(result)) {
1369 fail("GetNumberOfRedoItems() on redo stack with 4 items failed. (%d)\n",
1370 result);
1371 return result;
1372 }
1374 if (numitems != 4) {
1375 fail("GetNumberOfRedoItems() expected 4 got %d. (%d)\n",
1376 numitems, result);
1377 return NS_ERROR_FAILURE;
1378 }
1380 passed("Undo 4 transactions");
1382 /*******************************************************************
1383 *
1384 * Redo 2 transactions. Afterwards, we should have 8 transactions
1385 * on the undo stack, and 2 on the redo stack:
1386 *
1387 *******************************************************************/
1389 for (i = 1; i <= 2; ++i) {
1390 result = mgr->RedoTransaction();
1391 if (NS_FAILED(result)) {
1392 fail("Failed to redo transaction %d. (%d)\n", i, result);
1393 return result;
1394 }
1395 }
1397 result = mgr->GetNumberOfUndoItems(&numitems);
1399 if (NS_FAILED(result)) {
1400 fail("GetNumberOfUndoItems() on undo stack with 8 items failed. (%d)\n",
1401 result);
1402 return result;
1403 }
1405 if (numitems != 8) {
1406 fail("GetNumberOfUndoItems() expected 8 got %d. (%d)\n",
1407 numitems, result);
1408 return NS_ERROR_FAILURE;
1409 }
1411 result = mgr->GetNumberOfRedoItems(&numitems);
1413 if (NS_FAILED(result)) {
1414 fail("GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
1415 result);
1416 return result;
1417 }
1419 if (numitems != 2) {
1420 fail("GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
1421 numitems, result);
1422 return NS_ERROR_FAILURE;
1423 }
1425 passed("Redo 2 transactions");
1427 /*******************************************************************
1428 *
1429 * Execute a new transaction. The redo stack should get pruned!
1430 *
1431 *******************************************************************/
1433 tximpl = factory->create(mgr, NONE_FLAG);
1435 if (!tximpl) {
1436 fail("Failed to allocate transaction.\n");
1437 return NS_ERROR_OUT_OF_MEMORY;
1438 }
1440 tx = 0;
1442 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1444 if (NS_FAILED(result)) {
1445 fail("QueryInterface() failed for transaction. (%d)\n", result);
1446 return result;
1447 }
1449 result = mgr->DoTransaction(tx);
1450 if (NS_FAILED(result)) {
1451 fail("Failed to execute transaction. (%d)\n", result);
1452 return result;
1453 }
1455 tx->Release();
1457 result = mgr->GetNumberOfUndoItems(&numitems);
1459 if (NS_FAILED(result)) {
1460 fail("GetNumberOfUndoItems() on undo stack with 9 items failed. (%d)\n",
1461 result);
1462 return result;
1463 }
1465 if (numitems != 9) {
1466 fail("GetNumberOfUndoItems() expected 9 got %d. (%d)\n",
1467 numitems, result);
1468 return NS_ERROR_FAILURE;
1469 }
1471 result = mgr->GetNumberOfRedoItems(&numitems);
1473 if (NS_FAILED(result)) {
1474 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
1475 result);
1476 return result;
1477 }
1479 if (numitems != 0) {
1480 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1481 numitems, result);
1482 return NS_ERROR_FAILURE;
1483 }
1485 passed("Check if new transactions prune the redo stack");
1487 /*******************************************************************
1488 *
1489 * Undo 4 transactions then clear the undo and redo stacks.
1490 *
1491 *******************************************************************/
1493 for (i = 1; i <= 4; ++i) {
1494 result = mgr->UndoTransaction();
1495 if (NS_FAILED(result)) {
1496 fail("Failed to undo transaction %d. (%d)\n", i, result);
1497 return result;
1498 }
1499 }
1501 result = mgr->GetNumberOfUndoItems(&numitems);
1503 if (NS_FAILED(result)) {
1504 fail("GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
1505 result);
1506 return result;
1507 }
1509 if (numitems != 5) {
1510 fail("GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
1511 numitems, result);
1512 return NS_ERROR_FAILURE;
1513 }
1515 result = mgr->GetNumberOfRedoItems(&numitems);
1517 if (NS_FAILED(result)) {
1518 fail("GetNumberOfRedoItems() on redo stack with 4 items failed. (%d)\n",
1519 result);
1520 return result;
1521 }
1523 if (numitems != 4) {
1524 fail("GetNumberOfRedoItems() expected 4 got %d. (%d)\n",
1525 numitems, result);
1526 return NS_ERROR_FAILURE;
1527 }
1529 result = mgr->Clear();
1530 if (NS_FAILED(result)) {
1531 fail("Clear() failed. (%d)\n", result);
1532 return result;
1533 }
1535 result = mgr->GetNumberOfUndoItems(&numitems);
1537 if (NS_FAILED(result)) {
1538 fail("GetNumberOfUndoItems() on cleared undo stack failed. (%d)\n",
1539 result);
1540 return result;
1541 }
1543 if (numitems != 0) {
1544 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
1545 numitems, result);
1546 return NS_ERROR_FAILURE;
1547 }
1549 result = mgr->GetNumberOfRedoItems(&numitems);
1551 if (NS_FAILED(result)) {
1552 fail("GetNumberOfRedoItems() on cleared redo stack failed. (%d)\n",
1553 result);
1554 return result;
1555 }
1557 if (numitems != 0) {
1558 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1559 numitems, result);
1560 return NS_ERROR_FAILURE;
1561 }
1563 passed("Undo 4 transactions then clear the undo and redo stacks");
1565 /*******************************************************************
1566 *
1567 * Execute 5 transactions.
1568 *
1569 *******************************************************************/
1571 for (i = 1; i <= 5; i++) {
1572 tximpl = factory->create(mgr, NONE_FLAG);
1574 if (!tximpl) {
1575 fail("Failed to allocate transaction %d.\n", i);
1576 return NS_ERROR_OUT_OF_MEMORY;
1577 }
1579 tx = 0;
1580 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1581 if (NS_FAILED(result)) {
1582 fail("QueryInterface() failed for transaction %d. (%d)\n",
1583 i, result);
1584 return result;
1585 }
1587 result = mgr->DoTransaction(tx);
1588 if (NS_FAILED(result)) {
1589 fail("Failed to execute transaction %d. (%d)\n", i, result);
1590 return result;
1591 }
1593 tx->Release();
1594 }
1596 result = mgr->GetNumberOfUndoItems(&numitems);
1598 if (NS_FAILED(result)) {
1599 fail("GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
1600 result);
1601 return result;
1602 }
1604 if (numitems != 5) {
1605 fail("GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
1606 numitems, result);
1607 return NS_ERROR_FAILURE;
1608 }
1610 result = mgr->GetNumberOfRedoItems(&numitems);
1612 if (NS_FAILED(result)) {
1613 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
1614 result);
1615 return result;
1616 }
1618 if (numitems != 0) {
1619 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1620 numitems, result);
1621 return NS_ERROR_FAILURE;
1622 }
1624 passed("Execute 5 transactions");
1626 /*******************************************************************
1627 *
1628 * Test transaction DoTransaction() error:
1629 *
1630 *******************************************************************/
1632 tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
1634 if (!tximpl) {
1635 fail("Failed to allocate transaction.\n");
1636 return NS_ERROR_OUT_OF_MEMORY;
1637 }
1639 tx = 0;
1641 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1643 if (NS_FAILED(result)) {
1644 fail("QueryInterface() failed for transaction. (%d)\n", result);
1645 return result;
1646 }
1648 u1 = u2 = r1 = r2 = 0;
1650 result = mgr->PeekUndoStack(&u1);
1652 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
1654 if (NS_FAILED(result)) {
1655 fail("Initial PeekUndoStack() failed. (%d)\n", result);
1656 return result;
1657 }
1659 result = mgr->PeekRedoStack(&r1);
1661 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
1663 if (NS_FAILED(result)) {
1664 fail("Initial PeekRedoStack() failed. (%d)\n", result);
1665 return result;
1666 }
1668 result = mgr->DoTransaction(tx);
1670 if (result != NS_ERROR_FAILURE) {
1671 fail("DoTransaction() returned unexpected error. (%d)\n", result);
1672 return result;
1673 }
1675 tx->Release();
1677 result = mgr->PeekUndoStack(&u2);
1679 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
1681 if (NS_FAILED(result)) {
1682 fail("Second PeekUndoStack() failed. (%d)\n", result);
1683 return result;
1684 }
1686 if (u1 != u2) {
1687 fail("Top of undo stack changed. (%d)\n", result);
1688 return NS_ERROR_FAILURE;
1689 }
1691 result = mgr->PeekRedoStack(&r2);
1693 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
1695 if (NS_FAILED(result)) {
1696 fail("Second PeekRedoStack() failed. (%d)\n", result);
1697 return result;
1698 }
1700 if (r1 != r2) {
1701 fail("Top of redo stack changed. (%d)\n", result);
1702 return NS_ERROR_FAILURE;
1703 }
1705 result = mgr->GetNumberOfUndoItems(&numitems);
1707 if (NS_FAILED(result)) {
1708 fail("GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
1709 result);
1710 return result;
1711 }
1713 if (numitems != 5) {
1714 fail("GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
1715 numitems, result);
1716 return NS_ERROR_FAILURE;
1717 }
1719 result = mgr->GetNumberOfRedoItems(&numitems);
1721 if (NS_FAILED(result)) {
1722 fail("GetNumberOfRedoItems() on empty redo stack. (%d)\n",
1723 result);
1724 return result;
1725 }
1727 if (numitems != 0) {
1728 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1729 numitems, result);
1730 return NS_ERROR_FAILURE;
1731 }
1733 passed("Test transaction DoTransaction() error");
1735 /*******************************************************************
1736 *
1737 * Test transaction UndoTransaction() error:
1738 *
1739 *******************************************************************/
1741 tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
1743 if (!tximpl) {
1744 fail("Failed to allocate transaction.\n");
1745 return NS_ERROR_OUT_OF_MEMORY;
1746 }
1748 tx = 0;
1750 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1752 if (NS_FAILED(result)) {
1753 fail("QueryInterface() failed for transaction. (%d)\n", result);
1754 return result;
1755 }
1757 result = mgr->DoTransaction(tx);
1759 if (NS_FAILED(result)) {
1760 fail("DoTransaction() returned unexpected error. (%d)\n", result);
1761 return result;
1762 }
1764 tx->Release();
1766 u1 = u2 = r1 = r2 = 0;
1768 result = mgr->PeekUndoStack(&u1);
1770 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
1772 if (NS_FAILED(result)) {
1773 fail("Initial PeekUndoStack() failed. (%d)\n", result);
1774 return result;
1775 }
1777 result = mgr->PeekRedoStack(&r1);
1779 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
1781 if (NS_FAILED(result)) {
1782 fail("Initial PeekRedoStack() failed. (%d)\n", result);
1783 return result;
1784 }
1786 result = mgr->UndoTransaction();
1788 if (result != NS_ERROR_FAILURE) {
1789 fail("UndoTransaction() returned unexpected error. (%d)\n", result);
1790 return result;
1791 }
1793 result = mgr->PeekUndoStack(&u2);
1795 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
1797 if (NS_FAILED(result)) {
1798 fail("Second PeekUndoStack() failed. (%d)\n", result);
1799 return result;
1800 }
1802 if (u1 != u2) {
1803 fail("Top of undo stack changed. (%d)\n", result);
1804 return NS_ERROR_FAILURE;
1805 }
1807 result = mgr->PeekRedoStack(&r2);
1809 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
1811 if (NS_FAILED(result)) {
1812 fail("Second PeekRedoStack() failed. (%d)\n", result);
1813 return result;
1814 }
1816 if (r1 != r2) {
1817 fail("Top of redo stack changed. (%d)\n", result);
1818 return NS_ERROR_FAILURE;
1819 }
1821 result = mgr->GetNumberOfUndoItems(&numitems);
1823 if (NS_FAILED(result)) {
1824 fail("GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
1825 result);
1826 return result;
1827 }
1829 if (numitems != 6) {
1830 fail("GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
1831 numitems, result);
1832 return NS_ERROR_FAILURE;
1833 }
1835 result = mgr->GetNumberOfRedoItems(&numitems);
1837 if (NS_FAILED(result)) {
1838 fail("GetNumberOfRedoItems() on empty redo stack. (%d)\n",
1839 result);
1840 return result;
1841 }
1843 if (numitems != 0) {
1844 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
1845 numitems, result);
1846 return NS_ERROR_FAILURE;
1847 }
1849 passed("Test transaction UndoTransaction() error");
1851 /*******************************************************************
1852 *
1853 * Test transaction RedoTransaction() error:
1854 *
1855 *******************************************************************/
1857 tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
1859 if (!tximpl) {
1860 fail("Failed to allocate transaction.\n");
1861 return NS_ERROR_OUT_OF_MEMORY;
1862 }
1864 tx = 0;
1866 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1868 if (NS_FAILED(result)) {
1869 fail("QueryInterface() failed for RedoErrorTransaction. (%d)\n",
1870 result);
1871 return result;
1872 }
1874 result = mgr->DoTransaction(tx);
1876 if (NS_FAILED(result)) {
1877 fail("DoTransaction() returned unexpected error. (%d)\n", result);
1878 return result;
1879 }
1881 tx->Release();
1883 //
1884 // Execute a normal transaction to be used in a later test:
1885 //
1887 tximpl = factory->create(mgr, NONE_FLAG);
1889 if (!tximpl) {
1890 fail("Failed to allocate transaction.\n");
1891 return NS_ERROR_OUT_OF_MEMORY;
1892 }
1894 tx = 0;
1896 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
1898 if (NS_FAILED(result)) {
1899 fail("QueryInterface() failed for transaction. (%d)\n", result);
1900 return result;
1901 }
1903 result = mgr->DoTransaction(tx);
1905 if (NS_FAILED(result)) {
1906 fail("DoTransaction() returned unexpected error. (%d)\n", result);
1907 return result;
1908 }
1910 tx->Release();
1912 //
1913 // Undo the 2 transactions just executed.
1914 //
1916 for (i = 1; i <= 2; ++i) {
1917 result = mgr->UndoTransaction();
1918 if (NS_FAILED(result)) {
1919 fail("Failed to undo transaction %d. (%d)\n", i, result);
1920 return result;
1921 }
1922 }
1924 //
1925 // The RedoErrorTransaction should now be at the top of the redo stack!
1926 //
1928 u1 = u2 = r1 = r2 = 0;
1930 result = mgr->PeekUndoStack(&u1);
1932 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
1934 if (NS_FAILED(result)) {
1935 fail("Initial PeekUndoStack() failed. (%d)\n", result);
1936 return result;
1937 }
1939 result = mgr->PeekRedoStack(&r1);
1941 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
1943 if (NS_FAILED(result)) {
1944 fail("Initial PeekRedoStack() failed. (%d)\n", result);
1945 return result;
1946 }
1948 result = mgr->RedoTransaction();
1950 if (result != NS_ERROR_FAILURE) {
1951 fail("RedoTransaction() returned unexpected error. (%d)\n", result);
1952 return result;
1953 }
1955 result = mgr->PeekUndoStack(&u2);
1957 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
1959 if (NS_FAILED(result)) {
1960 fail("Second PeekUndoStack() failed. (%d)\n", result);
1961 return result;
1962 }
1964 if (u1 != u2) {
1965 fail("Top of undo stack changed. (%d)\n", result);
1966 return NS_ERROR_FAILURE;
1967 }
1969 result = mgr->PeekRedoStack(&r2);
1971 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
1973 if (NS_FAILED(result)) {
1974 fail("Second PeekRedoStack() failed. (%d)\n", result);
1975 return result;
1976 }
1978 if (r1 != r2) {
1979 fail("Top of redo stack changed. (%d)\n", result);
1980 return NS_ERROR_FAILURE;
1981 }
1983 result = mgr->GetNumberOfUndoItems(&numitems);
1985 if (NS_FAILED(result)) {
1986 fail("GetNumberOfUndoItems() on undo stack with 6 items failed. (%d)\n",
1987 result);
1988 return result;
1989 }
1991 if (numitems != 6) {
1992 fail("GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
1993 numitems, result);
1994 return NS_ERROR_FAILURE;
1995 }
1997 result = mgr->GetNumberOfRedoItems(&numitems);
1999 if (NS_FAILED(result)) {
2000 fail("GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
2001 result);
2002 return result;
2003 }
2005 if (numitems != 2) {
2006 fail("GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
2007 numitems, result);
2008 return NS_ERROR_FAILURE;
2009 }
2011 passed("Test transaction RedoTransaction() error");
2013 /*******************************************************************
2014 *
2015 * Make sure that setting the transaction manager's max transaction
2016 * count to zero, clears both the undo and redo stacks, and executes
2017 * all new commands without pushing them on the undo stack!
2018 *
2019 *******************************************************************/
2021 result = mgr->SetMaxTransactionCount(0);
2023 if (NS_FAILED(result)) {
2024 fail("SetMaxTransactionCount(0) failed. (%d)\n", result);
2025 return result;
2026 }
2028 result = mgr->GetNumberOfUndoItems(&numitems);
2030 if (NS_FAILED(result)) {
2031 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2032 result);
2033 return result;
2034 }
2036 if (numitems != 0) {
2037 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2038 numitems, result);
2039 return NS_ERROR_FAILURE;
2040 }
2042 result = mgr->GetNumberOfRedoItems(&numitems);
2044 if (NS_FAILED(result)) {
2045 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
2046 result);
2047 return result;
2048 }
2050 if (numitems != 0) {
2051 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
2052 numitems, result);
2053 return NS_ERROR_FAILURE;
2054 }
2056 for (i = 1; i <= 20; i++) {
2057 tximpl = factory->create(mgr, NONE_FLAG);
2059 if (!tximpl) {
2060 fail("Failed to allocate transaction %d.\n", i);
2061 return NS_ERROR_OUT_OF_MEMORY;
2062 }
2064 tx = 0;
2065 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
2066 if (NS_FAILED(result)) {
2067 fail("QueryInterface() failed for transaction %d. (%d)\n",
2068 i, result);
2069 return result;
2070 }
2072 result = mgr->DoTransaction(tx);
2073 if (NS_FAILED(result)) {
2074 fail("Failed to execute transaction %d. (%d)\n", i, result);
2075 return result;
2076 }
2078 tx->Release();
2080 result = mgr->GetNumberOfUndoItems(&numitems);
2082 if (NS_FAILED(result)) {
2083 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2084 result);
2085 return result;
2086 }
2088 if (numitems != 0) {
2089 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2090 numitems, result);
2091 return NS_ERROR_FAILURE;
2092 }
2094 result = mgr->GetNumberOfRedoItems(&numitems);
2096 if (NS_FAILED(result)) {
2097 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
2098 result);
2099 return result;
2100 }
2102 if (numitems != 0) {
2103 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
2104 numitems, result);
2105 return NS_ERROR_FAILURE;
2106 }
2107 }
2109 passed("Test max transaction count of zero");
2111 /*******************************************************************
2112 *
2113 * Make sure that setting the transaction manager's max transaction
2114 * count to something greater than the number of transactions on
2115 * both the undo and redo stacks causes no pruning of the stacks:
2116 *
2117 *******************************************************************/
2119 result = mgr->SetMaxTransactionCount(-1);
2121 if (NS_FAILED(result)) {
2122 fail("SetMaxTransactionCount(-1) failed. (%d)\n", result);
2123 return result;
2124 }
2126 // Push 20 transactions on the undo stack:
2128 for (i = 1; i <= 20; i++) {
2129 tximpl = factory->create(mgr, NONE_FLAG);
2131 if (!tximpl) {
2132 fail("Failed to allocate transaction %d.\n", i);
2133 return NS_ERROR_OUT_OF_MEMORY;
2134 }
2136 tx = 0;
2137 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
2138 if (NS_FAILED(result)) {
2139 fail("QueryInterface() failed for transaction %d. (%d)\n",
2140 i, result);
2141 return result;
2142 }
2144 result = mgr->DoTransaction(tx);
2145 if (NS_FAILED(result)) {
2146 fail("Failed to execute transaction %d. (%d)\n", i, result);
2147 return result;
2148 }
2150 tx->Release();
2152 result = mgr->GetNumberOfUndoItems(&numitems);
2154 if (NS_FAILED(result)) {
2155 fail("GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
2156 i, result);
2157 return result;
2158 }
2160 if (numitems != i) {
2161 fail("GetNumberOfUndoItems() expected %d got %d. (%d)\n",
2162 i, numitems, result);
2163 return NS_ERROR_FAILURE;
2164 }
2166 result = mgr->GetNumberOfRedoItems(&numitems);
2168 if (NS_FAILED(result)) {
2169 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
2170 result);
2171 return result;
2172 }
2174 if (numitems != 0) {
2175 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
2176 numitems, result);
2177 return NS_ERROR_FAILURE;
2178 }
2179 }
2181 for (i = 1; i <= 10; i++) {
2183 result = mgr->UndoTransaction();
2184 if (NS_FAILED(result)) {
2185 fail("Failed to undo transaction %d. (%d)\n", i, result);
2186 return result;
2187 }
2188 }
2189 result = mgr->GetNumberOfUndoItems(&numitems);
2191 if (NS_FAILED(result)) {
2192 fail("GetNumberOfUndoItems() on empty undo stack with 10 items failed. (%d)\n",
2193 result);
2194 return result;
2195 }
2197 if (numitems != 10) {
2198 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
2199 numitems, result);
2200 return NS_ERROR_FAILURE;
2201 }
2203 result = mgr->GetNumberOfRedoItems(&numitems);
2205 if (NS_FAILED(result)) {
2206 fail("GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
2207 result);
2208 return result;
2209 }
2211 if (numitems != 10) {
2212 fail("GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
2213 numitems, result);
2214 return NS_ERROR_FAILURE;
2215 }
2217 u1 = u2 = r1 = r2 = 0;
2219 result = mgr->PeekUndoStack(&u1);
2221 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
2223 if (NS_FAILED(result)) {
2224 fail("Initial PeekUndoStack() failed. (%d)\n", result);
2225 return result;
2226 }
2228 result = mgr->PeekRedoStack(&r1);
2230 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
2232 if (NS_FAILED(result)) {
2233 fail("Initial PeekRedoStack() failed. (%d)\n", result);
2234 return result;
2235 }
2237 result = mgr->SetMaxTransactionCount(25);
2239 if (NS_FAILED(result)) {
2240 fail("SetMaxTransactionCount(25) failed. (%d)\n", result);
2241 return result;
2242 }
2244 result = mgr->PeekUndoStack(&u2);
2246 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
2248 if (NS_FAILED(result)) {
2249 fail("Second PeekUndoStack() failed. (%d)\n", result);
2250 return result;
2251 }
2253 if (u1 != u2) {
2254 fail("Top of undo stack changed. (%d)\n", result);
2255 return NS_ERROR_FAILURE;
2256 }
2258 result = mgr->PeekRedoStack(&r2);
2260 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
2262 if (NS_FAILED(result)) {
2263 fail("Second PeekRedoStack() failed. (%d)\n", result);
2264 return result;
2265 }
2267 if (r1 != r2) {
2268 fail("Top of redo stack changed. (%d)\n", result);
2269 return NS_ERROR_FAILURE;
2270 }
2272 result = mgr->GetNumberOfUndoItems(&numitems);
2274 if (NS_FAILED(result)) {
2275 fail("GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
2276 result);
2277 return result;
2278 }
2280 if (numitems != 10) {
2281 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
2282 numitems, result);
2283 return NS_ERROR_FAILURE;
2284 }
2286 result = mgr->GetNumberOfRedoItems(&numitems);
2288 if (NS_FAILED(result)) {
2289 fail("GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
2290 result);
2291 return result;
2292 }
2294 if (numitems != 10) {
2295 fail("GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
2296 numitems, result);
2297 return NS_ERROR_FAILURE;
2298 }
2300 passed("Test SetMaxTransactionCount() greater than num stack items");
2302 /*******************************************************************
2303 *
2304 * Test undo stack pruning by setting the transaction
2305 * manager's max transaction count to a number lower than the
2306 * number of transactions on both the undo and redo stacks:
2307 *
2308 *******************************************************************/
2310 u1 = u2 = r1 = r2 = 0;
2312 result = mgr->PeekUndoStack(&u1);
2314 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
2316 if (NS_FAILED(result)) {
2317 fail("Initial PeekUndoStack() failed. (%d)\n", result);
2318 return result;
2319 }
2321 result = mgr->PeekRedoStack(&r1);
2323 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
2325 if (NS_FAILED(result)) {
2326 fail("Initial PeekRedoStack() failed. (%d)\n", result);
2327 return result;
2328 }
2330 result = mgr->SetMaxTransactionCount(15);
2332 if (NS_FAILED(result)) {
2333 fail("SetMaxTransactionCount(15) failed. (%d)\n", result);
2334 return result;
2335 }
2337 result = mgr->PeekUndoStack(&u2);
2339 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
2341 if (NS_FAILED(result)) {
2342 fail("Second PeekUndoStack() failed. (%d)\n", result);
2343 return result;
2344 }
2346 if (u1 != u2) {
2347 fail("Top of undo stack changed. (%d)\n", result);
2348 return NS_ERROR_FAILURE;
2349 }
2351 result = mgr->PeekRedoStack(&r2);
2353 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
2355 if (NS_FAILED(result)) {
2356 fail("Second PeekRedoStack() failed. (%d)\n", result);
2357 return result;
2358 }
2360 if (r1 != r2) {
2361 fail("Top of redo stack changed. (%d)\n", result);
2362 return NS_ERROR_FAILURE;
2363 }
2365 result = mgr->GetNumberOfUndoItems(&numitems);
2367 if (NS_FAILED(result)) {
2368 fail("GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
2369 result);
2370 return result;
2371 }
2373 if (numitems != 5) {
2374 fail("GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
2375 numitems, result);
2376 return NS_ERROR_FAILURE;
2377 }
2379 result = mgr->GetNumberOfRedoItems(&numitems);
2381 if (NS_FAILED(result)) {
2382 fail("GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
2383 result);
2384 return result;
2385 }
2387 if (numitems != 10) {
2388 fail("GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
2389 numitems, result);
2390 return NS_ERROR_FAILURE;
2391 }
2393 passed("Test SetMaxTransactionCount() pruning undo stack");
2395 /*******************************************************************
2396 *
2397 * Test redo stack pruning by setting the transaction
2398 * manager's max transaction count to a number lower than the
2399 * number of transactions on both the undo and redo stacks:
2400 *
2401 *******************************************************************/
2403 u1 = u2 = r1 = r2 = 0;
2405 result = mgr->PeekUndoStack(&u1);
2407 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
2409 if (NS_FAILED(result)) {
2410 fail("Initial PeekUndoStack() failed. (%d)\n", result);
2411 return result;
2412 }
2414 result = mgr->PeekRedoStack(&r1);
2416 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
2418 if (NS_FAILED(result)) {
2419 fail("Initial PeekRedoStack() failed. (%d)\n", result);
2420 return result;
2421 }
2423 result = mgr->SetMaxTransactionCount(5);
2425 if (NS_FAILED(result)) {
2426 fail("SetMaxTransactionCount(5) failed. (%d)\n", result);
2427 return result;
2428 }
2430 result = mgr->PeekUndoStack(&u2);
2432 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
2434 if (NS_FAILED(result)) {
2435 fail("Second PeekUndoStack() failed. (%d)\n", result);
2436 return result;
2437 }
2439 if (u2) {
2440 fail("Unexpected item at top of undo stack. (%d)\n", result);
2441 return NS_ERROR_FAILURE;
2442 }
2444 result = mgr->PeekRedoStack(&r2);
2446 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
2448 if (NS_FAILED(result)) {
2449 fail("Second PeekRedoStack() failed. (%d)\n", result);
2450 return result;
2451 }
2453 if (r1 != r2) {
2454 fail("Top of redo stack changed. (%d)\n", result);
2455 return NS_ERROR_FAILURE;
2456 }
2458 result = mgr->GetNumberOfUndoItems(&numitems);
2460 if (NS_FAILED(result)) {
2461 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2462 result);
2463 return result;
2464 }
2466 if (numitems != 0) {
2467 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2468 numitems, result);
2469 return NS_ERROR_FAILURE;
2470 }
2472 result = mgr->GetNumberOfRedoItems(&numitems);
2474 if (NS_FAILED(result)) {
2475 fail("GetNumberOfRedoItems() on redo stack with 5 items failed. (%d)\n",
2476 result);
2477 return result;
2478 }
2480 if (numitems != 5) {
2481 fail("GetNumberOfRedoItems() expected 5 got %d. (%d)\n",
2482 numitems, result);
2483 return NS_ERROR_FAILURE;
2484 }
2486 passed("Test SetMaxTransactionCount() pruning redo stack");
2488 /*******************************************************************
2489 *
2490 * Release the transaction manager. Any transactions on the undo
2491 * and redo stack should automatically be released:
2492 *
2493 *******************************************************************/
2495 result = mgr->SetMaxTransactionCount(-1);
2497 if (NS_FAILED(result)) {
2498 fail("SetMaxTransactionCount(-1) failed. (%d)\n", result);
2499 return result;
2500 }
2502 // Push 20 transactions on the undo stack:
2504 for (i = 1; i <= 20; i++) {
2505 tximpl = factory->create(mgr, NONE_FLAG);
2507 if (!tximpl) {
2508 fail("Failed to allocate transaction %d.\n", i);
2509 return NS_ERROR_OUT_OF_MEMORY;
2510 }
2512 tx = 0;
2513 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
2514 if (NS_FAILED(result)) {
2515 fail("QueryInterface() failed for transaction %d. (%d)\n",
2516 i, result);
2517 return result;
2518 }
2520 result = mgr->DoTransaction(tx);
2521 if (NS_FAILED(result)) {
2522 fail("Failed to execute transaction %d. (%d)\n", i, result);
2523 return result;
2524 }
2526 tx->Release();
2528 result = mgr->GetNumberOfUndoItems(&numitems);
2530 if (NS_FAILED(result)) {
2531 fail("GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
2532 i, result);
2533 return result;
2534 }
2536 if (numitems != i) {
2537 fail("GetNumberOfUndoItems() expected %d got %d. (%d)\n",
2538 i, numitems, result);
2539 return NS_ERROR_FAILURE;
2540 }
2542 result = mgr->GetNumberOfRedoItems(&numitems);
2544 if (NS_FAILED(result)) {
2545 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
2546 result);
2547 return result;
2548 }
2550 if (numitems != 0) {
2551 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
2552 numitems, result);
2553 return NS_ERROR_FAILURE;
2554 }
2555 }
2557 for (i = 1; i <= 10; i++) {
2559 result = mgr->UndoTransaction();
2560 if (NS_FAILED(result)) {
2561 fail("Failed to undo transaction %d. (%d)\n", i, result);
2562 return result;
2563 }
2564 }
2565 result = mgr->GetNumberOfUndoItems(&numitems);
2567 if (NS_FAILED(result)) {
2568 fail("GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
2569 result);
2570 return result;
2571 }
2573 if (numitems != 10) {
2574 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
2575 numitems, result);
2576 return NS_ERROR_FAILURE;
2577 }
2579 result = mgr->GetNumberOfRedoItems(&numitems);
2581 if (NS_FAILED(result)) {
2582 fail("GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
2583 result);
2584 return result;
2585 }
2587 if (numitems != 10) {
2588 fail("GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
2589 numitems, result);
2590 return NS_ERROR_FAILURE;
2591 }
2593 result = mgr->Clear();
2594 if (NS_FAILED(result)) {
2595 fail("Clear() failed. (%d)\n", result);
2596 return result;
2597 }
2599 passed("Release the transaction manager");
2601 /*******************************************************************
2602 *
2603 * Make sure number of transactions created matches number of
2604 * transactions destroyed!
2605 *
2606 *******************************************************************/
2608 /* Disabled because the current cycle collector doesn't delete
2609 cycle collectable objects synchronously.
2610 if (sConstructorCount != sDestructorCount) {
2611 fail("Transaction constructor count (%d) != destructor count (%d).\n",
2612 sConstructorCount, sDestructorCount);
2613 return NS_ERROR_FAILURE;
2614 }*/
2616 passed("Number of transactions created and destroyed match");
2617 passed("%d transactions processed during quick test", sConstructorCount);
2619 return NS_OK;
2620 }
2622 nsresult
2623 simple_test()
2624 {
2625 /*******************************************************************
2626 *
2627 * Initialize globals for test.
2628 *
2629 *******************************************************************/
2630 reset_globals();
2631 sDestructorOrderArr = sSimpleTestDestructorOrderArr;
2632 sDoOrderArr = sSimpleTestDoOrderArr;
2633 sUndoOrderArr = sSimpleTestUndoOrderArr;
2634 sRedoOrderArr = sSimpleTestRedoOrderArr;
2636 /*******************************************************************
2637 *
2638 * Run the quick test.
2639 *
2640 *******************************************************************/
2642 printf("\n-----------------------------------------------------\n");
2643 printf("- Begin Simple Transaction Test:\n");
2644 printf("-----------------------------------------------------\n");
2646 SimpleTransactionFactory factory;
2648 return quick_test(&factory);
2649 }
2651 nsresult
2652 aggregation_test()
2653 {
2654 /*******************************************************************
2655 *
2656 * Initialize globals for test.
2657 *
2658 *******************************************************************/
2660 reset_globals();
2661 sDestructorOrderArr = sAggregateTestDestructorOrderArr;
2662 sDoOrderArr = sAggregateTestDoOrderArr;
2663 sUndoOrderArr = sAggregateTestUndoOrderArr;
2664 sRedoOrderArr = sAggregateTestRedoOrderArr;
2666 /*******************************************************************
2667 *
2668 * Run the quick test.
2669 *
2670 *******************************************************************/
2672 printf("\n-----------------------------------------------------\n");
2673 printf("- Begin Aggregate Transaction Test:\n");
2674 printf("-----------------------------------------------------\n");
2676 AggregateTransactionFactory factory(3, 2);
2678 return quick_test(&factory);
2679 }
2681 /**
2682 * Test behaviors in batch mode.
2683 **/
2684 nsresult
2685 quick_batch_test(TestTransactionFactory *factory)
2686 {
2687 nsresult result;
2689 /*******************************************************************
2690 *
2691 * Create a transaction manager implementation:
2692 *
2693 *******************************************************************/
2695 nsCOMPtr<nsITransactionManager> mgr =
2696 do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
2697 if (NS_FAILED(result) || !mgr) {
2698 fail("Failed to create Transaction Manager instance.\n");
2699 return NS_ERROR_OUT_OF_MEMORY;
2700 }
2702 passed("Create transaction manager instance");
2704 int32_t numitems;
2706 /*******************************************************************
2707 *
2708 * Make sure an unbalanced call to EndBatch(false) with empty undo stack
2709 * throws an error!
2710 *
2711 *******************************************************************/
2713 result = mgr->GetNumberOfUndoItems(&numitems);
2715 if (NS_FAILED(result)) {
2716 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2717 result);
2718 return result;
2719 }
2721 if (numitems != 0) {
2722 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2723 numitems, result);
2724 return NS_ERROR_FAILURE;
2725 }
2727 result = mgr->EndBatch(false);
2729 if (result != NS_ERROR_FAILURE) {
2730 fail("EndBatch(false) returned unexpected status. (%d)\n", result);
2731 return result;
2732 }
2734 result = mgr->GetNumberOfUndoItems(&numitems);
2736 if (NS_FAILED(result)) {
2737 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2738 result);
2739 return result;
2740 }
2742 if (numitems != 0) {
2743 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2744 numitems, result);
2745 return NS_ERROR_FAILURE;
2746 }
2748 passed("Test unbalanced EndBatch(false) with empty undo stack");
2750 /*******************************************************************
2751 *
2752 * Make sure that an empty batch is not added to the undo stack
2753 * when it is closed.
2754 *
2755 *******************************************************************/
2757 result = mgr->GetNumberOfUndoItems(&numitems);
2759 if (NS_FAILED(result)) {
2760 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2761 result);
2762 return result;
2763 }
2765 if (numitems != 0) {
2766 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2767 numitems, result);
2768 return NS_ERROR_FAILURE;
2769 }
2771 result = mgr->BeginBatch(nullptr);
2773 if (NS_FAILED(result)) {
2774 fail("BeginBatch(nullptr) failed. (%d)\n", result);
2775 return result;
2776 }
2778 result = mgr->GetNumberOfUndoItems(&numitems);
2780 if (NS_FAILED(result)) {
2781 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2782 result);
2783 return result;
2784 }
2786 if (numitems != 0) {
2787 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2788 numitems, result);
2789 return NS_ERROR_FAILURE;
2790 }
2792 result = mgr->EndBatch(false);
2794 if (NS_FAILED(result)) {
2795 fail("EndBatch(false) failed. (%d)\n", result);
2796 return result;
2797 }
2799 result = mgr->GetNumberOfUndoItems(&numitems);
2801 if (NS_FAILED(result)) {
2802 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2803 result);
2804 return result;
2805 }
2807 if (numitems != 0) {
2808 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2809 numitems, result);
2810 return NS_ERROR_FAILURE;
2811 }
2813 passed("Test empty batch");
2815 int32_t i;
2816 TestTransaction *tximpl;
2817 nsITransaction *tx;
2819 /*******************************************************************
2820 *
2821 * Execute 20 transactions. Afterwards, we should have 1
2822 * transaction on the undo stack:
2823 *
2824 *******************************************************************/
2826 result = mgr->BeginBatch(nullptr);
2828 if (NS_FAILED(result)) {
2829 fail("BeginBatch(nullptr) failed. (%d)\n", result);
2830 return result;
2831 }
2833 for (i = 1; i <= 20; i++) {
2834 tximpl = factory->create(mgr, NONE_FLAG);
2836 if (!tximpl) {
2837 fail("Failed to allocate transaction %d.\n", i);
2838 return NS_ERROR_OUT_OF_MEMORY;
2839 }
2841 tx = 0;
2842 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
2843 if (NS_FAILED(result)) {
2844 fail("QueryInterface() failed for transaction %d. (%d)\n",
2845 i, result);
2846 return result;
2847 }
2849 result = mgr->DoTransaction(tx);
2850 if (NS_FAILED(result)) {
2851 fail("Failed to execute transaction %d. (%d)\n", i, result);
2852 return result;
2853 }
2855 tx->Release();
2856 }
2858 result = mgr->GetNumberOfUndoItems(&numitems);
2860 if (NS_FAILED(result)) {
2861 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
2862 result);
2863 return result;
2864 }
2866 if (numitems != 0) {
2867 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
2868 numitems, result);
2869 return NS_ERROR_FAILURE;
2870 }
2872 result = mgr->EndBatch(false);
2874 if (NS_FAILED(result)) {
2875 fail("EndBatch(false) failed. (%d)\n", result);
2876 return result;
2877 }
2879 result = mgr->GetNumberOfUndoItems(&numitems);
2881 if (NS_FAILED(result)) {
2882 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
2883 result);
2884 return result;
2885 }
2887 if (numitems != 1) {
2888 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
2889 numitems, result);
2890 return NS_ERROR_FAILURE;
2891 }
2893 passed("Execute 20 batched transactions");
2895 nsITransaction *u1, *u2;
2896 nsITransaction *r1, *r2;
2898 /*******************************************************************
2899 *
2900 * Execute 20 transient transactions. Afterwards, we should still
2901 * have the same transaction on the undo stack:
2902 *
2903 *******************************************************************/
2905 u1 = u2 = r1 = r2 = 0;
2907 result = mgr->PeekUndoStack(&u1);
2909 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
2911 if (NS_FAILED(result)) {
2912 fail("Initial PeekUndoStack() failed. (%d)\n", result);
2913 return result;
2914 }
2916 result = mgr->PeekRedoStack(&r1);
2918 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
2920 if (NS_FAILED(result)) {
2921 fail("Initial PeekRedoStack() failed. (%d)\n", result);
2922 return result;
2923 }
2925 result = mgr->BeginBatch(nullptr);
2927 if (NS_FAILED(result)) {
2928 fail("BeginBatch(nullptr) failed. (%d)\n", result);
2929 return result;
2930 }
2932 for (i = 1; i <= 20; i++) {
2933 tximpl = factory->create(mgr, TRANSIENT_FLAG);
2935 if (!tximpl) {
2936 fail("Failed to allocate transaction %d.\n", i);
2937 return NS_ERROR_OUT_OF_MEMORY;
2938 }
2940 tx = 0;
2941 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
2942 if (NS_FAILED(result)) {
2943 fail("QueryInterface() failed for transaction %d. (%d)\n",
2944 i, result);
2945 return result;
2946 }
2948 result = mgr->DoTransaction(tx);
2949 if (NS_FAILED(result)) {
2950 fail("Failed to execute transaction %d. (%d)\n", i, result);
2951 return result;
2952 }
2954 tx->Release();
2955 }
2957 result = mgr->EndBatch(false);
2959 if (NS_FAILED(result)) {
2960 fail("EndBatch(false) failed. (%d)\n", result);
2961 return result;
2962 }
2964 result = mgr->PeekUndoStack(&u2);
2966 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
2968 if (NS_FAILED(result)) {
2969 fail("Second PeekUndoStack() failed. (%d)\n", result);
2970 return result;
2971 }
2973 if (u1 != u2) {
2974 fail("Top of undo stack changed. (%d)\n", result);
2975 return NS_ERROR_FAILURE;
2976 }
2978 result = mgr->PeekRedoStack(&r2);
2980 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
2982 if (NS_FAILED(result)) {
2983 fail("Second PeekRedoStack() failed. (%d)\n", result);
2984 return result;
2985 }
2987 if (r1 != r2) {
2988 fail("Top of redo stack changed. (%d)\n", result);
2989 return NS_ERROR_FAILURE;
2990 }
2992 result = mgr->GetNumberOfUndoItems(&numitems);
2994 if (NS_FAILED(result)) {
2995 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
2996 result);
2997 return result;
2998 }
3000 if (numitems != 1) {
3001 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3002 numitems, result);
3003 return NS_ERROR_FAILURE;
3004 }
3006 result = mgr->GetNumberOfRedoItems(&numitems);
3008 if (NS_FAILED(result)) {
3009 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
3010 result);
3011 return result;
3012 }
3014 if (numitems != 0) {
3015 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
3016 numitems, result);
3017 return NS_ERROR_FAILURE;
3018 }
3020 passed("Execute 20 batched transient transactions");
3022 /*******************************************************************
3023 *
3024 * Test nested batching. Afterwards, we should have 2 transactions
3025 * on the undo stack:
3026 *
3027 *******************************************************************/
3029 result = mgr->BeginBatch(nullptr);
3031 if (NS_FAILED(result)) {
3032 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3033 return result;
3034 }
3036 tximpl = factory->create(mgr, NONE_FLAG);
3038 if (!tximpl) {
3039 fail("Failed to allocate transaction.\n");
3040 return NS_ERROR_OUT_OF_MEMORY;
3041 }
3043 tx = 0;
3044 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3045 if (NS_FAILED(result)) {
3046 fail("QueryInterface() failed for transaction. (%d)\n", result);
3047 return result;
3048 }
3050 result = mgr->DoTransaction(tx);
3051 if (NS_FAILED(result)) {
3052 fail("Failed to execute transaction. (%d)\n", result);
3053 return result;
3054 }
3056 tx->Release();
3058 result = mgr->GetNumberOfUndoItems(&numitems);
3060 if (NS_FAILED(result)) {
3061 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3062 result);
3063 return result;
3064 }
3066 if (numitems != 1) {
3067 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3068 numitems, result);
3069 return NS_ERROR_FAILURE;
3070 }
3072 result = mgr->BeginBatch(nullptr);
3074 if (NS_FAILED(result)) {
3075 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3076 return result;
3077 }
3079 tximpl = factory->create(mgr, NONE_FLAG);
3081 if (!tximpl) {
3082 fail("Failed to allocate transaction.\n");
3083 return NS_ERROR_OUT_OF_MEMORY;
3084 }
3086 tx = 0;
3087 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3088 if (NS_FAILED(result)) {
3089 fail("QueryInterface() failed for transaction. (%d)\n", result);
3090 return result;
3091 }
3093 result = mgr->DoTransaction(tx);
3094 if (NS_FAILED(result)) {
3095 fail("Failed to execute transaction. (%d)\n", result);
3096 return result;
3097 }
3099 tx->Release();
3101 result = mgr->GetNumberOfUndoItems(&numitems);
3103 if (NS_FAILED(result)) {
3104 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3105 result);
3106 return result;
3107 }
3109 if (numitems != 1) {
3110 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3111 numitems, result);
3112 return NS_ERROR_FAILURE;
3113 }
3115 result = mgr->BeginBatch(nullptr);
3117 if (NS_FAILED(result)) {
3118 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3119 return result;
3120 }
3122 tximpl = factory->create(mgr, NONE_FLAG);
3124 if (!tximpl) {
3125 fail("Failed to allocate transaction.\n");
3126 return NS_ERROR_OUT_OF_MEMORY;
3127 }
3129 tx = 0;
3130 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3131 if (NS_FAILED(result)) {
3132 fail("QueryInterface() failed for transaction. (%d)\n", result);
3133 return result;
3134 }
3136 result = mgr->DoTransaction(tx);
3137 if (NS_FAILED(result)) {
3138 fail("Failed to execute transaction. (%d)\n", result);
3139 return result;
3140 }
3142 tx->Release();
3144 result = mgr->GetNumberOfUndoItems(&numitems);
3146 if (NS_FAILED(result)) {
3147 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3148 result);
3149 return result;
3150 }
3152 if (numitems != 1) {
3153 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3154 numitems, result);
3155 return NS_ERROR_FAILURE;
3156 }
3158 result = mgr->EndBatch(false);
3160 if (NS_FAILED(result)) {
3161 fail("EndBatch(false) failed. (%d)\n", result);
3162 return result;
3163 }
3165 result = mgr->EndBatch(false);
3167 if (NS_FAILED(result)) {
3168 fail("EndBatch(false) failed. (%d)\n", result);
3169 return result;
3170 }
3172 result = mgr->EndBatch(false);
3174 if (NS_FAILED(result)) {
3175 fail("EndBatch(false) failed. (%d)\n", result);
3176 return result;
3177 }
3179 result = mgr->GetNumberOfUndoItems(&numitems);
3181 if (NS_FAILED(result)) {
3182 fail("GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
3183 result);
3184 return result;
3185 }
3187 if (numitems != 2) {
3188 fail("GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
3189 numitems, result);
3190 return NS_ERROR_FAILURE;
3191 }
3193 passed("Test nested batched transactions");
3195 /*******************************************************************
3196 *
3197 * Undo 2 batch transactions. Afterwards, we should have 0
3198 * transactions on the undo stack and 2 on the redo stack.
3199 *
3200 *******************************************************************/
3202 for (i = 1; i <= 2; ++i) {
3203 result = mgr->UndoTransaction();
3204 if (NS_FAILED(result)) {
3205 fail("Failed to undo transaction %d. (%d)\n", i, result);
3206 return result;
3207 }
3208 }
3210 result = mgr->GetNumberOfUndoItems(&numitems);
3212 if (NS_FAILED(result)) {
3213 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
3214 result);
3215 return result;
3216 }
3218 if (numitems != 0) {
3219 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
3220 numitems, result);
3221 return NS_ERROR_FAILURE;
3222 }
3224 result = mgr->GetNumberOfRedoItems(&numitems);
3226 if (NS_FAILED(result)) {
3227 fail("GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
3228 result);
3229 return result;
3230 }
3232 if (numitems != 2) {
3233 fail("GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
3234 numitems, result);
3235 return NS_ERROR_FAILURE;
3236 }
3238 passed("Undo 2 batch transactions");
3240 /*******************************************************************
3241 *
3242 * Redo 2 batch transactions. Afterwards, we should have 2
3243 * transactions on the undo stack and 0 on the redo stack.
3244 *
3245 *******************************************************************/
3247 for (i = 1; i <= 2; ++i) {
3248 result = mgr->RedoTransaction();
3249 if (NS_FAILED(result)) {
3250 fail("Failed to undo transaction %d. (%d)\n", i, result);
3251 return result;
3252 }
3253 }
3255 result = mgr->GetNumberOfUndoItems(&numitems);
3257 if (NS_FAILED(result)) {
3258 fail("GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
3259 result);
3260 return result;
3261 }
3263 if (numitems != 2) {
3264 fail("GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
3265 numitems, result);
3266 return NS_ERROR_FAILURE;
3267 }
3269 result = mgr->GetNumberOfRedoItems(&numitems);
3271 if (NS_FAILED(result)) {
3272 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
3273 result);
3274 return result;
3275 }
3277 if (numitems != 0) {
3278 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
3279 numitems, result);
3280 return NS_ERROR_FAILURE;
3281 }
3283 passed("Redo 2 batch transactions");
3285 /*******************************************************************
3286 *
3287 * Call undo. Afterwards, we should have 1 transaction
3288 * on the undo stack, and 1 on the redo stack:
3289 *
3290 *******************************************************************/
3292 result = mgr->UndoTransaction();
3294 if (NS_FAILED(result)) {
3295 fail("Failed to undo transaction. (%d)\n", result);
3296 return result;
3297 }
3299 result = mgr->GetNumberOfUndoItems(&numitems);
3301 if (NS_FAILED(result)) {
3302 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3303 result);
3304 return result;
3305 }
3307 if (numitems != 1) {
3308 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3309 numitems, result);
3310 return NS_ERROR_FAILURE;
3311 }
3313 result = mgr->GetNumberOfRedoItems(&numitems);
3315 if (NS_FAILED(result)) {
3316 fail("GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
3317 result);
3318 return result;
3319 }
3321 if (numitems != 1) {
3322 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3323 numitems, result);
3324 return NS_ERROR_FAILURE;
3325 }
3327 passed("Undo a batched transaction that was redone");
3329 /*******************************************************************
3330 *
3331 * Make sure an unbalanced call to EndBatch(false) throws an error and
3332 * doesn't affect the undo and redo stacks!
3333 *
3334 *******************************************************************/
3336 result = mgr->EndBatch(false);
3338 if (result != NS_ERROR_FAILURE) {
3339 fail("EndBatch(false) returned unexpected status. (%d)\n", result);
3340 return result;
3341 }
3343 result = mgr->GetNumberOfUndoItems(&numitems);
3345 if (NS_FAILED(result)) {
3346 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3347 result);
3348 return result;
3349 }
3351 if (numitems != 1) {
3352 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3353 numitems, result);
3354 return NS_ERROR_FAILURE;
3355 }
3357 result = mgr->GetNumberOfRedoItems(&numitems);
3359 if (NS_FAILED(result)) {
3360 fail("GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
3361 result);
3362 return result;
3363 }
3365 if (numitems != 1) {
3366 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3367 numitems, result);
3368 return NS_ERROR_FAILURE;
3369 }
3371 passed("Test effect of unbalanced EndBatch(false) on undo and redo stacks");
3373 /*******************************************************************
3374 *
3375 * Make sure that an empty batch is not added to the undo stack
3376 * when it is closed, and that it does not affect the undo and redo
3377 * stacks.
3378 *
3379 *******************************************************************/
3381 result = mgr->BeginBatch(nullptr);
3383 if (NS_FAILED(result)) {
3384 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3385 return result;
3386 }
3388 result = mgr->GetNumberOfUndoItems(&numitems);
3390 if (NS_FAILED(result)) {
3391 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3392 result);
3393 return result;
3394 }
3396 if (numitems != 1) {
3397 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3398 numitems, result);
3399 return NS_ERROR_FAILURE;
3400 }
3402 result = mgr->GetNumberOfRedoItems(&numitems);
3404 if (NS_FAILED(result)) {
3405 fail("GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
3406 result);
3407 return result;
3408 }
3410 if (numitems != 1) {
3411 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3412 numitems, result);
3413 return NS_ERROR_FAILURE;
3414 }
3416 result = mgr->EndBatch(false);
3418 if (NS_FAILED(result)) {
3419 fail("EndBatch(false) failed. (%d)\n", result);
3420 return result;
3421 }
3423 result = mgr->GetNumberOfUndoItems(&numitems);
3425 if (NS_FAILED(result)) {
3426 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3427 result);
3428 return result;
3429 }
3431 if (numitems != 1) {
3432 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3433 numitems, result);
3434 return NS_ERROR_FAILURE;
3435 }
3437 result = mgr->GetNumberOfRedoItems(&numitems);
3439 if (NS_FAILED(result)) {
3440 fail("GetNumberOfRedoItems() on stack with 1 item failed. (%d)\n",
3441 result);
3442 return result;
3443 }
3445 if (numitems != 1) {
3446 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3447 numitems, result);
3448 return NS_ERROR_FAILURE;
3449 }
3451 passed("Test effect of empty batch on undo and redo stacks");
3453 /*******************************************************************
3454 *
3455 * Execute a new transaction. The redo stack should get pruned!
3456 *
3457 *******************************************************************/
3459 result = mgr->BeginBatch(nullptr);
3461 if (NS_FAILED(result)) {
3462 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3463 return result;
3464 }
3466 for (i = 1; i <= 20; i++) {
3467 tximpl = factory->create(mgr, NONE_FLAG);
3469 if (!tximpl) {
3470 fail("Failed to allocate transaction %d.\n", i);
3471 return NS_ERROR_OUT_OF_MEMORY;
3472 }
3474 tx = 0;
3475 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3476 if (NS_FAILED(result)) {
3477 fail("QueryInterface() failed for transaction %d. (%d)\n",
3478 i, result);
3479 return result;
3480 }
3482 result = mgr->DoTransaction(tx);
3483 if (NS_FAILED(result)) {
3484 fail("Failed to execute transaction %d. (%d)\n", i, result);
3485 return result;
3486 }
3488 tx->Release();
3489 }
3491 result = mgr->GetNumberOfUndoItems(&numitems);
3493 if (NS_FAILED(result)) {
3494 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3495 result);
3496 return result;
3497 }
3499 if (numitems != 1) {
3500 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3501 numitems, result);
3502 return NS_ERROR_FAILURE;
3503 }
3505 result = mgr->GetNumberOfRedoItems(&numitems);
3507 if (NS_FAILED(result)) {
3508 fail("GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
3509 result);
3510 return result;
3511 }
3513 if (numitems != 1) {
3514 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3515 numitems, result);
3516 return NS_ERROR_FAILURE;
3517 }
3519 result = mgr->EndBatch(false);
3521 if (NS_FAILED(result)) {
3522 fail("EndBatch(false) failed. (%d)\n", result);
3523 return result;
3524 }
3526 result = mgr->GetNumberOfUndoItems(&numitems);
3528 if (NS_FAILED(result)) {
3529 fail("GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
3530 result);
3531 return result;
3532 }
3534 if (numitems != 2) {
3535 fail("GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
3536 numitems, result);
3537 return NS_ERROR_FAILURE;
3538 }
3540 result = mgr->GetNumberOfRedoItems(&numitems);
3542 if (NS_FAILED(result)) {
3543 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
3544 result);
3545 return result;
3546 }
3548 if (numitems != 0) {
3549 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
3550 numitems, result);
3551 return NS_ERROR_FAILURE;
3552 }
3554 passed("Check if new batched transactions prune the redo stack");
3556 /*******************************************************************
3557 *
3558 * Call undo.
3559 *
3560 *******************************************************************/
3562 // Move a transaction over to the redo stack, so that we have one
3563 // transaction on the undo stack, and one on the redo stack!
3565 result = mgr->UndoTransaction();
3567 if (NS_FAILED(result)) {
3568 fail("Failed to undo transaction. (%d)\n", result);
3569 return result;
3570 }
3572 result = mgr->GetNumberOfUndoItems(&numitems);
3574 if (NS_FAILED(result)) {
3575 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3576 result);
3577 return result;
3578 }
3580 if (numitems != 1) {
3581 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3582 numitems, result);
3583 return NS_ERROR_FAILURE;
3584 }
3586 result = mgr->GetNumberOfRedoItems(&numitems);
3588 if (NS_FAILED(result)) {
3589 fail("GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
3590 result);
3591 return result;
3592 }
3594 if (numitems != 1) {
3595 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3596 numitems, result);
3597 return NS_ERROR_FAILURE;
3598 }
3600 passed("Call undo");
3602 /*******************************************************************
3603 *
3604 * Test transaction DoTransaction() error:
3605 *
3606 *******************************************************************/
3608 tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
3610 if (!tximpl) {
3611 fail("Failed to allocate transaction.\n");
3612 return NS_ERROR_OUT_OF_MEMORY;
3613 }
3615 tx = 0;
3617 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3619 if (NS_FAILED(result)) {
3620 fail("QueryInterface() failed for transaction. (%d)\n", result);
3621 return result;
3622 }
3624 u1 = u2 = r1 = r2 = 0;
3626 result = mgr->PeekUndoStack(&u1);
3628 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
3630 if (NS_FAILED(result)) {
3631 fail("Initial PeekUndoStack() failed. (%d)\n", result);
3632 return result;
3633 }
3635 result = mgr->PeekRedoStack(&r1);
3637 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
3639 if (NS_FAILED(result)) {
3640 fail("Initial PeekRedoStack() failed. (%d)\n", result);
3641 return result;
3642 }
3644 result = mgr->BeginBatch(nullptr);
3646 if (NS_FAILED(result)) {
3647 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3648 return result;
3649 }
3651 result = mgr->DoTransaction(tx);
3653 if (result != NS_ERROR_FAILURE) {
3654 fail("DoTransaction() returned unexpected error. (%d)\n", result);
3655 return result;
3656 }
3658 tx->Release();
3660 result = mgr->EndBatch(false);
3662 if (NS_FAILED(result)) {
3663 fail("EndBatch(false) failed. (%d)\n", result);
3664 return result;
3665 }
3667 result = mgr->PeekUndoStack(&u2);
3669 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
3671 if (NS_FAILED(result)) {
3672 fail("Second PeekUndoStack() failed. (%d)\n", result);
3673 return result;
3674 }
3676 if (u1 != u2) {
3677 fail("Top of undo stack changed. (%d)\n", result);
3678 return NS_ERROR_FAILURE;
3679 }
3681 result = mgr->PeekRedoStack(&r2);
3683 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
3685 if (NS_FAILED(result)) {
3686 fail("Second PeekRedoStack() failed. (%d)\n", result);
3687 return result;
3688 }
3690 if (r1 != r2) {
3691 fail("Top of redo stack changed. (%d)\n", result);
3692 return NS_ERROR_FAILURE;
3693 }
3695 result = mgr->GetNumberOfUndoItems(&numitems);
3697 if (NS_FAILED(result)) {
3698 fail("GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
3699 result);
3700 return result;
3701 }
3703 if (numitems != 1) {
3704 fail("GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
3705 numitems, result);
3706 return NS_ERROR_FAILURE;
3707 }
3709 result = mgr->GetNumberOfRedoItems(&numitems);
3711 if (NS_FAILED(result)) {
3712 fail("GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
3713 result);
3714 return result;
3715 }
3717 if (numitems != 1) {
3718 fail("GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
3719 numitems, result);
3720 return NS_ERROR_FAILURE;
3721 }
3723 passed("Test transaction DoTransaction() error");
3725 /*******************************************************************
3726 *
3727 * Test transaction UndoTransaction() error:
3728 *
3729 *******************************************************************/
3731 tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
3733 if (!tximpl) {
3734 fail("Failed to allocate transaction.\n");
3735 return NS_ERROR_OUT_OF_MEMORY;
3736 }
3738 tx = 0;
3740 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3742 if (NS_FAILED(result)) {
3743 fail("QueryInterface() failed for transaction. (%d)\n", result);
3744 return result;
3745 }
3747 result = mgr->BeginBatch(nullptr);
3749 if (NS_FAILED(result)) {
3750 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3751 return result;
3752 }
3754 result = mgr->DoTransaction(tx);
3756 if (NS_FAILED(result)) {
3757 fail("DoTransaction() returned unexpected error. (%d)\n", result);
3758 return result;
3759 }
3761 tx->Release();
3763 result = mgr->EndBatch(false);
3765 if (NS_FAILED(result)) {
3766 fail("EndBatch(false) failed. (%d)\n", result);
3767 return result;
3768 }
3770 u1 = u2 = r1 = r2 = 0;
3772 result = mgr->PeekUndoStack(&u1);
3774 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
3776 if (NS_FAILED(result)) {
3777 fail("Initial PeekUndoStack() failed. (%d)\n", result);
3778 return result;
3779 }
3781 result = mgr->PeekRedoStack(&r1);
3783 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
3785 if (NS_FAILED(result)) {
3786 fail("Initial PeekRedoStack() failed. (%d)\n", result);
3787 return result;
3788 }
3790 result = mgr->UndoTransaction();
3792 if (result != NS_ERROR_FAILURE) {
3793 fail("UndoTransaction() returned unexpected error. (%d)\n", result);
3794 return result;
3795 }
3797 result = mgr->PeekUndoStack(&u2);
3799 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
3801 if (NS_FAILED(result)) {
3802 fail("Second PeekUndoStack() failed. (%d)\n", result);
3803 return result;
3804 }
3806 if (u1 != u2) {
3807 fail("Top of undo stack changed. (%d)\n", result);
3808 return NS_ERROR_FAILURE;
3809 }
3811 result = mgr->PeekRedoStack(&r2);
3813 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
3815 if (NS_FAILED(result)) {
3816 fail("Second PeekRedoStack() failed. (%d)\n", result);
3817 return result;
3818 }
3820 if (r1 != r2) {
3821 fail("Top of redo stack changed. (%d)\n", result);
3822 return NS_ERROR_FAILURE;
3823 }
3825 result = mgr->GetNumberOfUndoItems(&numitems);
3827 if (NS_FAILED(result)) {
3828 fail("GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
3829 result);
3830 return result;
3831 }
3833 if (numitems != 2) {
3834 fail("GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
3835 numitems, result);
3836 return NS_ERROR_FAILURE;
3837 }
3839 result = mgr->GetNumberOfRedoItems(&numitems);
3841 if (NS_FAILED(result)) {
3842 fail("GetNumberOfRedoItems() on empty redo stack. (%d)\n",
3843 result);
3844 return result;
3845 }
3847 if (numitems != 0) {
3848 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
3849 numitems, result);
3850 return NS_ERROR_FAILURE;
3851 }
3853 passed("Test transaction UndoTransaction() error");
3855 /*******************************************************************
3856 *
3857 * Test transaction RedoTransaction() error:
3858 *
3859 *******************************************************************/
3861 tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
3863 if (!tximpl) {
3864 fail("Failed to allocate transaction.\n");
3865 return NS_ERROR_OUT_OF_MEMORY;
3866 }
3868 tx = 0;
3870 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3872 if (NS_FAILED(result)) {
3873 fail("QueryInterface() failed for RedoErrorTransaction. (%d)\n",
3874 result);
3875 return result;
3876 }
3878 result = mgr->BeginBatch(nullptr);
3880 if (NS_FAILED(result)) {
3881 fail("BeginBatch(nullptr) failed. (%d)\n", result);
3882 return result;
3883 }
3885 result = mgr->DoTransaction(tx);
3887 if (NS_FAILED(result)) {
3888 fail("DoTransaction() returned unexpected error. (%d)\n", result);
3889 return result;
3890 }
3892 tx->Release();
3894 result = mgr->EndBatch(false);
3896 if (NS_FAILED(result)) {
3897 fail("EndBatch(false) failed. (%d)\n", result);
3898 return result;
3899 }
3901 //
3902 // Execute a normal transaction to be used in a later test:
3903 //
3905 tximpl = factory->create(mgr, NONE_FLAG);
3907 if (!tximpl) {
3908 fail("Failed to allocate transaction.\n");
3909 return NS_ERROR_OUT_OF_MEMORY;
3910 }
3912 tx = 0;
3914 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
3916 if (NS_FAILED(result)) {
3917 fail("QueryInterface() failed for transaction. (%d)\n", result);
3918 return result;
3919 }
3921 result = mgr->DoTransaction(tx);
3923 if (NS_FAILED(result)) {
3924 fail("DoTransaction() returned unexpected error. (%d)\n", result);
3925 return result;
3926 }
3928 tx->Release();
3930 //
3931 // Undo the 2 transactions just executed.
3932 //
3934 for (i = 1; i <= 2; ++i) {
3935 result = mgr->UndoTransaction();
3936 if (NS_FAILED(result)) {
3937 fail("Failed to undo transaction %d. (%d)\n", i, result);
3938 return result;
3939 }
3940 }
3942 //
3943 // The RedoErrorTransaction should now be at the top of the redo stack!
3944 //
3946 u1 = u2 = r1 = r2 = 0;
3948 result = mgr->PeekUndoStack(&u1);
3950 TEST_TXMGR_IF_RELEASE(u1); // Don't hold onto any references!
3952 if (NS_FAILED(result)) {
3953 fail("Initial PeekUndoStack() failed. (%d)\n", result);
3954 return result;
3955 }
3957 result = mgr->PeekRedoStack(&r1);
3959 TEST_TXMGR_IF_RELEASE(r1); // Don't hold onto any references!
3961 if (NS_FAILED(result)) {
3962 fail("Initial PeekRedoStack() failed. (%d)\n", result);
3963 return result;
3964 }
3966 result = mgr->RedoTransaction();
3968 if (result != NS_ERROR_FAILURE) {
3969 fail("RedoTransaction() returned unexpected error. (%d)\n", result);
3970 return result;
3971 }
3973 result = mgr->PeekUndoStack(&u2);
3975 TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
3977 if (NS_FAILED(result)) {
3978 fail("Second PeekUndoStack() failed. (%d)\n", result);
3979 return result;
3980 }
3982 if (u1 != u2) {
3983 fail("Top of undo stack changed. (%d)\n", result);
3984 return NS_ERROR_FAILURE;
3985 }
3987 result = mgr->PeekRedoStack(&r2);
3989 TEST_TXMGR_IF_RELEASE(r2); // Don't hold onto any references!
3991 if (NS_FAILED(result)) {
3992 fail("Second PeekRedoStack() failed. (%d)\n", result);
3993 return result;
3994 }
3996 if (r1 != r2) {
3997 fail("Top of redo stack changed. (%d)\n", result);
3998 return NS_ERROR_FAILURE;
3999 }
4001 result = mgr->GetNumberOfUndoItems(&numitems);
4003 if (NS_FAILED(result)) {
4004 fail("GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
4005 result);
4006 return result;
4007 }
4009 if (numitems != 2) {
4010 fail("GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
4011 numitems, result);
4012 return NS_ERROR_FAILURE;
4013 }
4015 result = mgr->GetNumberOfRedoItems(&numitems);
4017 if (NS_FAILED(result)) {
4018 fail("GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
4019 result);
4020 return result;
4021 }
4023 if (numitems != 2) {
4024 fail("GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
4025 numitems, result);
4026 return NS_ERROR_FAILURE;
4027 }
4029 passed("Test transaction RedoTransaction() error");
4031 /*******************************************************************
4032 *
4033 * Make sure that setting the transaction manager's max transaction
4034 * count to zero, clears both the undo and redo stacks, and executes
4035 * all new commands without pushing them on the undo stack!
4036 *
4037 *******************************************************************/
4039 result = mgr->SetMaxTransactionCount(0);
4041 if (NS_FAILED(result)) {
4042 fail("SetMaxTransactionCount(0) failed. (%d)\n", result);
4043 return result;
4044 }
4046 result = mgr->GetNumberOfUndoItems(&numitems);
4048 if (NS_FAILED(result)) {
4049 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
4050 result);
4051 return result;
4052 }
4054 if (numitems != 0) {
4055 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
4056 numitems, result);
4057 return NS_ERROR_FAILURE;
4058 }
4060 result = mgr->GetNumberOfRedoItems(&numitems);
4062 if (NS_FAILED(result)) {
4063 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
4064 result);
4065 return result;
4066 }
4068 if (numitems != 0) {
4069 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
4070 numitems, result);
4071 return NS_ERROR_FAILURE;
4072 }
4074 for (i = 1; i <= 20; i++) {
4075 tximpl = factory->create(mgr, NONE_FLAG);
4077 if (!tximpl) {
4078 fail("Failed to allocate transaction %d.\n", i);
4079 return NS_ERROR_OUT_OF_MEMORY;
4080 }
4082 tx = 0;
4083 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
4084 if (NS_FAILED(result)) {
4085 fail("QueryInterface() failed for transaction %d. (%d)\n",
4086 i, result);
4087 return result;
4088 }
4090 result = mgr->BeginBatch(nullptr);
4092 if (NS_FAILED(result)) {
4093 fail("BeginBatch(nullptr) failed. (%d)\n", result);
4094 return result;
4095 }
4097 result = mgr->DoTransaction(tx);
4098 if (NS_FAILED(result)) {
4099 fail("Failed to execute transaction %d. (%d)\n", i, result);
4100 return result;
4101 }
4103 tx->Release();
4105 result = mgr->EndBatch(false);
4107 if (NS_FAILED(result)) {
4108 fail("EndBatch(false) failed. (%d)\n", result);
4109 return result;
4110 }
4112 result = mgr->GetNumberOfUndoItems(&numitems);
4114 if (NS_FAILED(result)) {
4115 fail("GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
4116 result);
4117 return result;
4118 }
4120 if (numitems != 0) {
4121 fail("GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
4122 numitems, result);
4123 return NS_ERROR_FAILURE;
4124 }
4126 result = mgr->GetNumberOfRedoItems(&numitems);
4128 if (NS_FAILED(result)) {
4129 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
4130 result);
4131 return result;
4132 }
4134 if (numitems != 0) {
4135 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
4136 numitems, result);
4137 return NS_ERROR_FAILURE;
4138 }
4139 }
4141 passed("Test max transaction count of zero");
4143 /*******************************************************************
4144 *
4145 * Release the transaction manager. Any transactions on the undo
4146 * and redo stack should automatically be released:
4147 *
4148 *******************************************************************/
4150 result = mgr->SetMaxTransactionCount(-1);
4152 if (NS_FAILED(result)) {
4153 fail("SetMaxTransactionCount(0) failed. (%d)\n", result);
4154 return result;
4155 }
4157 // Push 20 transactions on the undo stack:
4159 for (i = 1; i <= 20; i++) {
4160 tximpl = factory->create(mgr, NONE_FLAG);
4162 if (!tximpl) {
4163 fail("Failed to allocate transaction %d.\n", i);
4164 return NS_ERROR_OUT_OF_MEMORY;
4165 }
4167 tx = 0;
4168 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
4169 if (NS_FAILED(result)) {
4170 fail("QueryInterface() failed for transaction %d. (%d)\n",
4171 i, result);
4172 return result;
4173 }
4175 result = mgr->BeginBatch(nullptr);
4177 if (NS_FAILED(result)) {
4178 fail("BeginBatch(nullptr) failed. (%d)\n", result);
4179 return result;
4180 }
4182 result = mgr->DoTransaction(tx);
4183 if (NS_FAILED(result)) {
4184 fail("Failed to execute transaction %d. (%d)\n", i, result);
4185 return result;
4186 }
4188 tx->Release();
4190 result = mgr->EndBatch(false);
4192 if (NS_FAILED(result)) {
4193 fail("EndBatch(false) failed. (%d)\n", result);
4194 return result;
4195 }
4197 result = mgr->GetNumberOfUndoItems(&numitems);
4199 if (NS_FAILED(result)) {
4200 fail("GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
4201 i, result);
4202 return result;
4203 }
4205 if (numitems != i) {
4206 fail("GetNumberOfUndoItems() expected %d got %d. (%d)\n",
4207 i, numitems, result);
4208 return NS_ERROR_FAILURE;
4209 }
4211 result = mgr->GetNumberOfRedoItems(&numitems);
4213 if (NS_FAILED(result)) {
4214 fail("GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
4215 result);
4216 return result;
4217 }
4219 if (numitems != 0) {
4220 fail("GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
4221 numitems, result);
4222 return NS_ERROR_FAILURE;
4223 }
4224 }
4226 for (i = 1; i <= 10; i++) {
4228 result = mgr->UndoTransaction();
4229 if (NS_FAILED(result)) {
4230 fail("Failed to undo transaction %d. (%d)\n", i, result);
4231 return result;
4232 }
4233 }
4234 result = mgr->GetNumberOfUndoItems(&numitems);
4236 if (NS_FAILED(result)) {
4237 fail("GetNumberOfUndoItems() on empty undo stack with 10 items failed. (%d)\n",
4238 result);
4239 return result;
4240 }
4242 if (numitems != 10) {
4243 fail("GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
4244 numitems, result);
4245 return NS_ERROR_FAILURE;
4246 }
4248 result = mgr->GetNumberOfRedoItems(&numitems);
4250 if (NS_FAILED(result)) {
4251 fail("GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
4252 result);
4253 return result;
4254 }
4256 if (numitems != 10) {
4257 fail("GetNumberOfRedoItems() expected 10 got %d. (%d)\n",
4258 numitems, result);
4259 return NS_ERROR_FAILURE;
4260 }
4262 result = mgr->Clear();
4263 if (NS_FAILED(result)) {
4264 fail("Clear() failed. (%d)\n", result);
4265 return result;
4266 }
4268 passed("Release the transaction manager");
4270 /*******************************************************************
4271 *
4272 * Make sure number of transactions created matches number of
4273 * transactions destroyed!
4274 *
4275 *******************************************************************/
4277 /* Disabled because the current cycle collector doesn't delete
4278 cycle collectable objects synchronously.
4279 if (sConstructorCount != sDestructorCount) {
4280 fail("Transaction constructor count (%d) != destructor count (%d).\n",
4281 sConstructorCount, sDestructorCount);
4282 return NS_ERROR_FAILURE;
4283 }*/
4285 passed("Number of transactions created and destroyed match");
4286 passed("%d transactions processed during quick batch test",
4287 sConstructorCount);
4289 return NS_OK;
4290 }
4292 nsresult
4293 simple_batch_test()
4294 {
4295 /*******************************************************************
4296 *
4297 * Initialize globals for test.
4298 *
4299 *******************************************************************/
4300 reset_globals();
4301 sDestructorOrderArr = sSimpleBatchTestDestructorOrderArr;
4302 sDoOrderArr = sSimpleBatchTestDoOrderArr;
4303 sUndoOrderArr = sSimpleBatchTestUndoOrderArr;
4304 sRedoOrderArr = sSimpleBatchTestRedoOrderArr;
4306 /*******************************************************************
4307 *
4308 * Run the quick batch test.
4309 *
4310 *******************************************************************/
4312 printf("\n-----------------------------------------------------\n");
4313 printf("- Begin Batch Transaction Test:\n");
4314 printf("-----------------------------------------------------\n");
4316 SimpleTransactionFactory factory;
4318 return quick_batch_test(&factory);
4319 }
4321 nsresult
4322 aggregation_batch_test()
4323 {
4324 /*******************************************************************
4325 *
4326 * Initialize globals for test.
4327 *
4328 *******************************************************************/
4330 reset_globals();
4331 sDestructorOrderArr = sAggregateBatchTestDestructorOrderArr;
4332 sDoOrderArr = sAggregateBatchTestDoOrderArr;
4333 sUndoOrderArr = sAggregateBatchTestUndoOrderArr;
4334 sRedoOrderArr = sAggregateBatchTestRedoOrderArr;
4336 /*******************************************************************
4337 *
4338 * Run the quick batch test.
4339 *
4340 *******************************************************************/
4342 printf("\n-----------------------------------------------------\n");
4343 printf("- Begin Batch Aggregate Transaction Test:\n");
4344 printf("-----------------------------------------------------\n");
4346 AggregateTransactionFactory factory(3, 2, BATCH_FLAG);
4348 return quick_batch_test(&factory);
4349 }
4351 /**
4352 * Create 'iterations * (iterations + 1) / 2' transactions;
4353 * do/undo/redo/undo them.
4354 **/
4355 nsresult
4356 stress_test(TestTransactionFactory *factory, int32_t iterations)
4357 {
4358 printf("Stress test of %i iterations (may take a while) ... ", iterations);
4359 fflush(stdout);
4361 nsresult result;
4363 /*******************************************************************
4364 *
4365 * Create a transaction manager:
4366 *
4367 *******************************************************************/
4369 nsCOMPtr<nsITransactionManager> mgr =
4370 do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
4371 if (NS_FAILED(result) || !mgr) {
4372 fail("Failed to create Transaction Manager instance.\n");
4373 return NS_ERROR_OUT_OF_MEMORY;
4374 }
4376 int32_t i, j;
4377 nsITransaction *tx;
4379 for (i = 1; i <= iterations; i++) {
4380 /*******************************************************************
4381 *
4382 * Create and execute a bunch of transactions:
4383 *
4384 *******************************************************************/
4386 for (j = 1; j <= i; j++) {
4387 TestTransaction *tximpl = factory->create(mgr, NONE_FLAG);
4389 if (!tximpl) {
4390 fail("Failed to allocate transaction %d-%d.\n", i, j);
4391 return NS_ERROR_OUT_OF_MEMORY;
4392 }
4394 tx = 0;
4395 result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
4396 if (NS_FAILED(result)) {
4397 fail("QueryInterface() failed for transaction %d-%d. (%d)\n",
4398 i, j, result);
4399 return result;
4400 }
4402 result = mgr->DoTransaction(tx);
4403 if (NS_FAILED(result)) {
4404 fail("Failed to execute transaction %d-%d. (%d)\n",
4405 i, j, result);
4406 return result;
4407 }
4409 tx->Release();
4410 }
4412 /*******************************************************************
4413 *
4414 * Undo all the transactions:
4415 *
4416 *******************************************************************/
4418 for (j = 1; j <= i; j++) {
4419 result = mgr->UndoTransaction();
4420 if (NS_FAILED(result)) {
4421 fail("Failed to undo transaction %d-%d. (%d)\n", i, j, result);
4422 return result;
4423 }
4424 }
4426 /*******************************************************************
4427 *
4428 * Redo all the transactions:
4429 *
4430 *******************************************************************/
4432 for (j = 1; j <= i; j++) {
4433 result = mgr->RedoTransaction();
4434 if (NS_FAILED(result)) {
4435 fail("Failed to redo transaction %d-%d. (%d)\n", i, j, result);
4436 return result;
4437 }
4438 }
4440 /*******************************************************************
4441 *
4442 * Undo all the transactions again so that they all end up on
4443 * the redo stack for pruning the next time we execute a new
4444 * transaction
4445 *
4446 *******************************************************************/
4448 for (j = 1; j <= i; j++) {
4449 result = mgr->UndoTransaction();
4450 if (NS_FAILED(result)) {
4451 fail("Failed to undo transaction %d-%d. (%d)\n", i, j, result);
4452 return result;
4453 }
4454 }
4456 // Trivial feedback not to let the user think the test is stuck.
4457 if (MOZ_UNLIKELY(j % 100 == 0))
4458 printf("%i ", j);
4459 } // for, iterations.
4461 printf("passed\n");
4463 result = mgr->Clear();
4464 if (NS_FAILED(result)) {
4465 fail("Clear() failed. (%d)\n", result);
4466 return result;
4467 }
4469 /* Disabled because the current cycle collector doesn't delete
4470 cycle collectable objects synchronously.
4471 if (sConstructorCount != sDestructorCount) {
4472 fail("Transaction constructor count (%d) != destructor count (%d).\n",
4473 sConstructorCount, sDestructorCount);
4474 return NS_ERROR_FAILURE;
4475 }*/
4477 passed("%d transactions processed during stress test", sConstructorCount);
4479 return NS_OK;
4480 }
4482 nsresult
4483 simple_stress_test()
4484 {
4485 /*******************************************************************
4486 *
4487 * Initialize globals for test.
4488 *
4489 *******************************************************************/
4491 reset_globals();
4493 /*******************************************************************
4494 *
4495 * Do the stress test:
4496 *
4497 *******************************************************************/
4499 printf("\n-----------------------------------------------------\n");
4500 printf("- Simple Transaction Stress Test:\n");
4501 printf("-----------------------------------------------------\n");
4503 SimpleTransactionFactory factory;
4505 int32_t iterations =
4506 #ifdef DEBUG
4507 10
4508 #else
4509 //
4510 // 1500 iterations sends 1,125,750 transactions through the system!!
4511 //
4512 1500
4513 #endif
4514 ;
4515 return stress_test(&factory, iterations);
4516 }
4518 nsresult
4519 aggregation_stress_test()
4520 {
4521 /*******************************************************************
4522 *
4523 * Initialize globals for test.
4524 *
4525 *******************************************************************/
4527 reset_globals();
4529 /*******************************************************************
4530 *
4531 * Do the stress test:
4532 *
4533 *******************************************************************/
4535 printf("\n-----------------------------------------------------\n");
4536 printf("- Aggregate Transaction Stress Test:\n");
4537 printf("-----------------------------------------------------\n");
4539 AggregateTransactionFactory factory(3, 4);
4541 int32_t iterations =
4542 #ifdef DEBUG
4543 10
4544 #else
4545 //
4546 // 500 iterations sends 2,630,250 transactions through the system!!
4547 //
4548 500
4549 #endif
4550 ;
4551 return stress_test(&factory, iterations);
4552 }
4554 nsresult
4555 aggregation_batch_stress_test()
4556 {
4557 /*******************************************************************
4558 *
4559 * Initialize globals for test.
4560 *
4561 *******************************************************************/
4563 reset_globals();
4565 /*******************************************************************
4566 *
4567 * Do the stress test:
4568 *
4569 *******************************************************************/
4571 printf("\n-----------------------------------------------------\n");
4572 printf("- Aggregate Batch Transaction Stress Test:\n");
4573 printf("-----------------------------------------------------\n");
4575 AggregateTransactionFactory factory(3, 4, BATCH_FLAG);
4577 int32_t iterations =
4578 #ifdef DEBUG
4579 10
4580 #else
4581 #if defined(MOZ_ASAN) || defined(MOZ_WIDGET_ANDROID)
4582 // See Bug 929985: 500 is too many for ASAN and Android, 100 is safe.
4583 100
4584 #else
4585 //
4586 // 500 iterations sends 2,630,250 transactions through the system!!
4587 //
4588 500
4589 #endif
4590 #endif
4591 ;
4592 return stress_test(&factory, iterations);
4593 }
4595 int
4596 main (int argc, char *argv[])
4597 {
4598 ScopedXPCOM xpcom("nsITransactionManager");
4599 if (xpcom.failed())
4600 return 1;
4602 nsresult result;
4604 //
4605 // quick_test() part:
4606 //
4608 result = simple_test();
4609 NS_ENSURE_SUCCESS(result, 1);
4611 result = aggregation_test();
4612 NS_ENSURE_SUCCESS(result, 1);
4614 //
4615 // quick_batch_test() part:
4616 //
4618 result = simple_batch_test();
4619 NS_ENSURE_SUCCESS(result, 1);
4621 result = aggregation_batch_test();
4622 NS_ENSURE_SUCCESS(result, 1);
4624 //
4625 // stress_test() part:
4626 //
4628 result = simple_stress_test();
4629 NS_ENSURE_SUCCESS(result, 1);
4631 result = aggregation_stress_test();
4632 NS_ENSURE_SUCCESS(result, 1);
4634 result = aggregation_batch_stress_test();
4635 NS_ENSURE_SUCCESS(result, 1);
4637 return 0;
4638 }