MDL-41254 backup Raise time and memory limit in precheck.
[moodle.git] / mdeploytest.php
CommitLineData
89af1765
DM
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * PHPUnit tests for the mdeploy.php utility
20 *
21 * Because the mdeploy.php can't be part of the Moodle code itself, this tests must be
22 * executed using something like:
23 *
24 * $ phpunit --no-configuration mdeploytest
25 *
26 * @package core
27 * @copyright 2012 David Mudrak <david@moodle.com>
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 */
30
31require(__DIR__.'/mdeploy.php');
32
33/**
34 * Provides testable input options.
35 *
36 * @copyright 2012 David Mudrak <david@moodle.com>
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 */
39class input_fake_provider extends input_provider {
40
41 /** @var array */
42 protected $fakeoptions = array();
43
44 /**
45 * Sets fake raw options.
46 *
47 * @param array $options
48 */
49 public function set_fake_options(array $options) {
50 $this->fakeoptions = $options;
51 $this->populate_options();
52 }
53
54 /**
55 * Returns the explicitly set fake options.
56 *
57 * @return array
58 */
59 protected function parse_raw_options() {
60 return $this->fakeoptions;
61 }
62}
63
64/**
65 * Testable subclass.
66 *
67 * @copyright 2012 David Mudrak <david@moodle.com>
68 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
69 */
70class testable_input_manager extends input_manager {
71
72 /**
73 * Provides access to the protected method so we can test it explicitly.
74 */
75 public function cast_value($raw, $type) {
76 return parent::cast_value($raw, $type);
77 }
78
79 /**
80 * Sets the fake input provider.
81 */
82 protected function initialize() {
83 $this->inputprovider = input_fake_provider::instance();
84 }
85}
86
87
dabe5acc
DM
88/**
89 * Testable subclass
90 *
91 * @copyright 2012 David Mudrak <david@moodle.com>
92 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
93 */
94class testable_worker extends worker {
95
96 /**
97 * Provides access to the protected method.
98 */
99 public function move_directory($source, $target, $keepsourceroot = false) {
100 return parent::move_directory($source, $target, $keepsourceroot);
101 }
102
103 /**
104 * Provides access to the protected method.
105 */
106 public function remove_directory($path, $keeppathroot = false) {
107 return parent::remove_directory($path, $keeppathroot);
108 }
203b4321
DM
109
110 /**
111 * Provides access to the protected method.
112 */
113 public function create_directory_precheck($path) {
114 return parent::create_directory_precheck($path);
115 }
dabe5acc
DM
116}
117
118
89af1765
DM
119/**
120 * Test cases for the mdeploy utility
121 *
122 * @copyright 2012 David Mudrak <david@moodle.com>
123 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
124 */
125class mdeploytest extends PHPUnit_Framework_TestCase {
126
127 public function test_same_singletons() {
128 $a = input_manager::instance();
129 $b = input_manager::instance();
130 $this->assertSame($a, $b);
131 }
132
133 /**
134 * @dataProvider data_for_cast_value
135 */
136 public function test_cast_value($raw, $type, $result) {
137 $input = testable_input_manager::instance();
138 $this->assertSame($input->cast_value($raw, $type), $result);
139 }
140
141 public function data_for_cast_value() {
142 return array(
143 array('3', input_manager::TYPE_INT, 3),
144 array(4, input_manager::TYPE_INT, 4),
145 array('', input_manager::TYPE_INT, 0),
146
147 array(true, input_manager::TYPE_FLAG, true),
148 array(false, input_manager::TYPE_FLAG, true),
149 array(0, input_manager::TYPE_FLAG, true),
150 array('1', input_manager::TYPE_FLAG, true),
151 array('0', input_manager::TYPE_FLAG, true),
152 array('muhehe', input_manager::TYPE_FLAG, true),
c57f18ad 153
5230f6a7
DM
154 array('C:\\WINDOWS\\user.dat', input_manager::TYPE_PATH, 'C:/WINDOWS/user.dat'),
155 array('D:\xampp\htdocs\24_integration/mdeploy.php', input_manager::TYPE_PATH, 'D:/xampp/htdocs/24_integration/mdeploy.php'),
156 array('d:/xampp/htdocs/24_integration/mdeploy.php', input_manager::TYPE_PATH, 'd:/xampp/htdocs/24_integration/mdeploy.php'),
c57f18ad
DM
157 array('../../../etc/passwd', input_manager::TYPE_PATH, '/etc/passwd'),
158 array('///////.././public_html/test.php', input_manager::TYPE_PATH, '/public_html/test.php'),
159
160 array("!@#$%|/etc/qwerty\n\n\t\n\r", input_manager::TYPE_RAW, "!@#$%|/etc/qwerty\n\n\t\n\r"),
161
162 array("\nrock'n'roll.mp3\t.exe", input_manager::TYPE_FILE, 'rocknroll.mp3.exe'),
4c72f555
DM
163
164 array('http://localhost/moodle/dev/plugin.zip', input_manager::TYPE_URL, 'http://localhost/moodle/dev/plugin.zip'),
165 array(
166 'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip',
167 input_manager::TYPE_URL,
168 'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip'
169 ),
6b75106a
DM
170
171 array('5e8d2ea4f50d154730100b1645fbad67', input_manager::TYPE_MD5, '5e8d2ea4f50d154730100b1645fbad67'),
89af1765
DM
172 );
173 }
174
5230f6a7
DM
175 /**
176 * @expectedException invalid_option_exception
177 */
178 public function test_input_type_path_multiple_colons() {
179 $input = testable_input_manager::instance();
180 $input->cast_value('C:\apache\log:file', input_manager::TYPE_PATH); // must throw exception
181 }
182
183 /**
184 * @expectedException invalid_option_exception
185 */
186 public function test_input_type_path_invalid_drive_label() {
187 $input = testable_input_manager::instance();
188 $input->cast_value('0:/srv/moodledata', input_manager::TYPE_PATH); // must throw exception
189 }
190
191 /**
192 * @expectedException invalid_option_exception
193 */
194 public function test_input_type_path_invalid_colon() {
195 $input = testable_input_manager::instance();
196 $input->cast_value('/var/www/moodle:2.5', input_manager::TYPE_PATH); // must throw exception
197 }
198
89af1765
DM
199 /**
200 * @expectedException invalid_coding_exception
201 */
202 public function test_cast_array_argument() {
203 $input = testable_input_manager::instance();
204 $input->cast_value(array(1, 2, 3), input_manager::TYPE_INT); // must throw exception
205 }
206
207 /**
208 * @expectedException invalid_coding_exception
209 */
210 public function test_cast_object_argument() {
211 $input = testable_input_manager::instance();
212 $o = new stdClass();
213 $input->cast_value($o, input_manager::TYPE_INT); // must throw exception
214 }
215
5bd9b0ae
DM
216 /**
217 * @expectedException invalid_option_exception
218 */
219 public function test_cast_invalid_url_value() {
220 $input = testable_input_manager::instance();
221 $invalid = 'file:///etc/passwd';
222 $input->cast_value($invalid, input_manager::TYPE_URL); // must throw exception
223 }
224
6b75106a
DM
225 /**
226 * @expectedException invalid_option_exception
227 */
228 public function test_cast_invalid_md5_value() {
229 $input = testable_input_manager::instance();
230 $invalid = 'this is not a valid md5 hash';
231 $input->cast_value($invalid, input_manager::TYPE_MD5); // must throw exception
232 }
233
8ffa8d7e
DM
234 /**
235 * @expectedException invalid_option_exception
236 */
237 public function test_cast_tilde_in_path() {
238 $input = testable_input_manager::instance();
239 $invalid = '~/public_html/moodle_dev';
240 $input->cast_value($invalid, input_manager::TYPE_PATH); // must throw exception
241 }
242
89af1765
DM
243 public function test_has_option() {
244 $provider = input_fake_provider::instance();
245
246 $provider->set_fake_options(array());
247 $this->assertFalse($provider->has_option('foo')); // foo not passed
248
249 $provider->set_fake_options(array('foo' => 1));
250 $this->assertFalse($provider->has_option('foo')); // foo passed but not a known option
251
252 $provider->set_fake_options(array('foo' => 1, 'help' => false));
253 $this->assertTrue($provider->has_option('help')); // help passed and it is a flag (value ignored)
254 $this->assertTrue($provider->has_option('h')); // 'h' is a shortname for 'help'
255 }
11c3c579
DM
256
257 public function test_get_option() {
258 $input = testable_input_manager::instance();
259 $provider = input_fake_provider::instance();
260
261 $provider->set_fake_options(array('help' => false, 'passfile' => '_mdeploy.123456'));
262 $this->assertTrue($input->get_option('h'));
263 $this->assertEquals($input->get_option('passfile'), '_mdeploy.123456');
264 $this->assertEquals($input->get_option('password', 'admin123'), 'admin123');
265 try {
266 $this->assertEquals($input->get_option('password'), 'admin123'); // must throw exception (not passed but required)
267 $this->assertTrue(false);
268 } catch (missing_option_exception $e) {
269 $this->assertTrue(true);
270 }
271 }
dabe5acc
DM
272
273 public function test_moving_and_removing_directories() {
274 $worker = testable_worker::instance();
275
276 $root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
277 mkdir($root.'/a', 0777, true);
278 touch($root.'/a/a.txt');
279
280 $this->assertTrue(file_exists($root.'/a/a.txt'));
281 $this->assertFalse(file_exists($root.'/b/a.txt'));
282 $this->assertTrue($worker->move_directory($root.'/a', $root.'/b'));
283 $this->assertFalse(is_dir($root.'/a'));
284 $this->assertTrue(file_exists($root.'/b/a.txt'));
285 $this->assertTrue($worker->move_directory($root.'/b', $root.'/c', true));
286 $this->assertTrue(file_exists($root.'/c/a.txt'));
287 $this->assertFalse(file_exists($root.'/b/a.txt'));
288 $this->assertTrue(is_dir($root.'/b'));
289 $this->assertTrue($worker->remove_directory($root.'/c', true));
290 $this->assertFalse(file_exists($root.'/c/a.txt'));
291 $this->assertTrue($worker->remove_directory($root.'/c'));
292 $this->assertFalse(is_dir($root.'/c'));
293 }
203b4321
DM
294
295 public function test_create_directory_precheck() {
296 $worker = testable_worker::instance();
297
298 $root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
299 $this->assertFalse(file_exists($root));
300 $this->assertTrue($worker->create_directory_precheck($root));
301 $this->assertFalse(file_exists($root)); // The precheck is supposed to remove it again.
302 }
89af1765 303}