Merge "Begin exposing SiteConfiguration via site contexts"
[lhc/web/wiklou.git] / tests / phpunit / maintenance / backup_LogTest.php
1 <?php
2 /**
3 * Tests for log dumps of BackupDumper
4 *
5 * @group Database
6 * @group Dump
7 * @covers BackupDumper
8 */
9 class BackupDumperLoggerTest extends DumpTestCase {
10
11 // We'll add several log entries and users for this test. The following
12 // variables hold the corresponding ids.
13 private $userId1, $userId2;
14 private $logId1, $logId2, $logId3;
15
16 /**
17 * adds a log entry to the database.
18 *
19 * @param $type string: type of the log entry
20 * @param $subtype string: subtype of the log entry
21 * @param $user User: user that performs the logged operation
22 * @param $ns int: number of the namespace for the entry's target's title
23 * @param $title string: title of the entry's target
24 * @param $comment string: comment of the log entry
25 * @param $parameters Array: (optional) accompanying data that is attached
26 * to the entry
27 *
28 * @return int id of the added log entry
29 */
30 private function addLogEntry( $type, $subtype, User $user, $ns, $title,
31 $comment = null, $parameters = null
32 ) {
33 $logEntry = new ManualLogEntry( $type, $subtype );
34 $logEntry->setPerformer( $user );
35 $logEntry->setTarget( Title::newFromText( $title, $ns ) );
36 if ( $comment !== null ) {
37 $logEntry->setComment( $comment );
38 }
39 if ( $parameters !== null ) {
40 $logEntry->setParameters( $parameters );
41 }
42
43 return $logEntry->insert();
44 }
45
46 function addDBData() {
47 $this->tablesUsed[] = 'logging';
48 $this->tablesUsed[] = 'user';
49
50 try {
51 $user1 = User::newFromName( 'BackupDumperLogUserA' );
52 $this->userId1 = $user1->getId();
53 if ( $this->userId1 === 0 ) {
54 $user1->addToDatabase();
55 $this->userId1 = $user1->getId();
56 }
57 $this->assertGreaterThan( 0, $this->userId1 );
58
59 $user2 = User::newFromName( 'BackupDumperLogUserB' );
60 $this->userId2 = $user2->getId();
61 if ( $this->userId2 === 0 ) {
62 $user2->addToDatabase();
63 $this->userId2 = $user2->getId();
64 }
65 $this->assertGreaterThan( 0, $this->userId2 );
66
67 $this->logId1 = $this->addLogEntry( 'type', 'subtype',
68 $user1, NS_MAIN, "PageA" );
69 $this->assertGreaterThan( 0, $this->logId1 );
70
71 $this->logId2 = $this->addLogEntry( 'supress', 'delete',
72 $user2, NS_TALK, "PageB", "SomeComment" );
73 $this->assertGreaterThan( 0, $this->logId2 );
74
75 $this->logId3 = $this->addLogEntry( 'move', 'delete',
76 $user2, NS_MAIN, "PageA", "SomeOtherComment",
77 array( 'key1' => 1, 3 => 'value3' ) );
78 $this->assertGreaterThan( 0, $this->logId3 );
79 } catch ( Exception $e ) {
80 // We'd love to pass $e directly. However, ... see
81 // documentation of exceptionFromAddDBData in
82 // DumpTestCase
83 $this->exceptionFromAddDBData = $e;
84 }
85 }
86
87 /**
88 * asserts that the xml reader is at the beginning of a log entry and skips over
89 * it while analyzing it.
90 *
91 * @param $id int: id of the log entry
92 * @param $user_name string: user name of the log entry's performer
93 * @param $user_id int: user id of the log entry 's performer
94 * @param $comment string|null: comment of the log entry. If null, the comment
95 * text is ignored.
96 * @param $type string: type of the log entry
97 * @param $subtype string: subtype of the log entry
98 * @param $title string: title of the log entry's target
99 * @param $parameters array: (optional) unserialized data accompanying the log entry
100 */
101 private function assertLogItem( $id, $user_name, $user_id, $comment, $type,
102 $subtype, $title, $parameters = array()
103 ) {
104
105 $this->assertNodeStart( "logitem" );
106 $this->skipWhitespace();
107
108 $this->assertTextNode( "id", $id );
109 $this->assertTextNode( "timestamp", false );
110
111 $this->assertNodeStart( "contributor" );
112 $this->skipWhitespace();
113 $this->assertTextNode( "username", $user_name );
114 $this->assertTextNode( "id", $user_id );
115 $this->assertNodeEnd( "contributor" );
116 $this->skipWhitespace();
117
118 if ( $comment !== null ) {
119 $this->assertTextNode( "comment", $comment );
120 }
121 $this->assertTextNode( "type", $type );
122 $this->assertTextNode( "action", $subtype );
123 $this->assertTextNode( "logtitle", $title );
124
125 $this->assertNodeStart( "params" );
126 $parameters_xml = unserialize( $this->xml->value );
127 $this->assertEquals( $parameters, $parameters_xml );
128 $this->assertTrue( $this->xml->read(), "Skipping past processed text of params" );
129 $this->assertNodeEnd( "params" );
130 $this->skipWhitespace();
131
132 $this->assertNodeEnd( "logitem" );
133 $this->skipWhitespace();
134 }
135
136 function testPlain() {
137 global $wgContLang;
138
139 // Preparing the dump
140 $fname = $this->getNewTempFile();
141 $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
142 $dumper->startId = $this->logId1;
143 $dumper->endId = $this->logId3 + 1;
144 $dumper->reporting = false;
145 $dumper->setDb( $this->db );
146
147 // Performing the dump
148 $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT );
149
150 // Analyzing the dumped data
151 $this->assertDumpStart( $fname );
152
153 $this->assertLogItem( $this->logId1, "BackupDumperLogUserA",
154 $this->userId1, null, "type", "subtype", "PageA" );
155
156 $this->assertNotNull( $wgContLang, "Content language object validation" );
157 $namespace = $wgContLang->getNsText( NS_TALK );
158 $this->assertInternalType( 'string', $namespace );
159 $this->assertGreaterThan( 0, strlen( $namespace ) );
160 $this->assertLogItem( $this->logId2, "BackupDumperLogUserB",
161 $this->userId2, "SomeComment", "supress", "delete",
162 $namespace . ":PageB" );
163
164 $this->assertLogItem( $this->logId3, "BackupDumperLogUserB",
165 $this->userId2, "SomeOtherComment", "move", "delete",
166 "PageA", array( 'key1' => 1, 3 => 'value3' ) );
167
168 $this->assertDumpEnd();
169 }
170
171 function testXmlDumpsBackupUseCaseLogging() {
172 global $wgContLang;
173
174 $this->checkHasGzip();
175
176 // Preparing the dump
177 $fname = $this->getNewTempFile();
178 $dumper = new BackupDumper( array( "--output=gzip:" . $fname,
179 "--reporting=2" ) );
180 $dumper->startId = $this->logId1;
181 $dumper->endId = $this->logId3 + 1;
182 $dumper->setDb( $this->db );
183
184 // xmldumps-backup demands reporting, although this is currently not
185 // implemented in BackupDumper, when dumping logging data. We
186 // nevertheless capture the output of the dump process already now,
187 // to be able to alert (once dumping produces reports) that this test
188 // needs updates.
189 $dumper->stderr = fopen( 'php://output', 'a' );
190 if ( $dumper->stderr === false ) {
191 $this->fail( "Could not open stream for stderr" );
192 }
193
194 // Performing the dump
195 $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT );
196
197 $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" );
198
199 // Analyzing the dumped data
200 $this->gunzip( $fname );
201
202 $this->assertDumpStart( $fname );
203
204 $this->assertLogItem( $this->logId1, "BackupDumperLogUserA",
205 $this->userId1, null, "type", "subtype", "PageA" );
206
207 $this->assertNotNull( $wgContLang, "Content language object validation" );
208 $namespace = $wgContLang->getNsText( NS_TALK );
209 $this->assertInternalType( 'string', $namespace );
210 $this->assertGreaterThan( 0, strlen( $namespace ) );
211 $this->assertLogItem( $this->logId2, "BackupDumperLogUserB",
212 $this->userId2, "SomeComment", "supress", "delete",
213 $namespace . ":PageB" );
214
215 $this->assertLogItem( $this->logId3, "BackupDumperLogUserB",
216 $this->userId2, "SomeOtherComment", "move", "delete",
217 "PageA", array( 'key1' => 1, 3 => 'value3' ) );
218
219 $this->assertDumpEnd();
220
221 // Currently, no reporting is implemented. Alert via failure, once
222 // this changes.
223 // If reporting for log dumps has been implemented, please update
224 // the following statement to catch good output
225 $this->expectOutputString( '' );
226 }
227 }