3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * PHPUnit tests for the mdeploy.php utility
21 * Because the mdeploy.php can't be part of the Moodle code itself, this tests must be
22 * executed using something like:
24 * $ phpunit --no-configuration mdeploytest
27 * @copyright 2012 David Mudrak <david@moodle.com>
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 require(__DIR__
.'/mdeploy.php');
34 * Provides testable input options.
36 * @copyright 2012 David Mudrak <david@moodle.com>
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 class input_fake_provider
extends input_provider
{
42 protected $fakeoptions = array();
45 * Sets fake raw options.
47 * @param array $options
49 public function set_fake_options(array $options) {
50 $this->fakeoptions
= $options;
51 $this->populate_options();
55 * Returns the explicitly set fake options.
59 protected function parse_raw_options() {
60 return $this->fakeoptions
;
67 * @copyright 2012 David Mudrak <david@moodle.com>
68 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
70 class testable_input_manager
extends input_manager
{
73 * Provides access to the protected method so we can test it explicitly.
75 public function cast_value($raw, $type) {
76 return parent
::cast_value($raw, $type);
80 * Sets the fake input provider.
82 protected function initialize() {
83 $this->inputprovider
= input_fake_provider
::instance();
91 * @copyright 2012 David Mudrak <david@moodle.com>
92 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
94 class testable_worker
extends worker
{
97 * Provides access to the protected method.
99 public function move_directory($source, $target, $keepsourceroot = false) {
100 return parent
::move_directory($source, $target, $keepsourceroot);
104 * Provides access to the protected method.
106 public function remove_directory($path, $keeppathroot = false) {
107 return parent
::remove_directory($path, $keeppathroot);
111 * Provides access to the protected method.
113 public function create_directory_precheck($path) {
114 return parent
::create_directory_precheck($path);
117 public function get_env($key) {
118 return parent
::get_env($key);
124 * Test cases for the mdeploy utility
126 * @copyright 2012 David Mudrak <david@moodle.com>
127 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
129 class mdeploytest
extends PHPUnit_Framework_TestCase
{
131 public function test_same_singletons() {
132 $a = input_manager
::instance();
133 $b = input_manager
::instance();
134 $this->assertSame($a, $b);
138 * @dataProvider data_for_cast_value
140 public function test_cast_value($raw, $type, $result) {
141 $input = testable_input_manager
::instance();
142 $this->assertSame($input->cast_value($raw, $type), $result);
145 public function data_for_cast_value() {
147 array('3', input_manager
::TYPE_INT
, 3),
148 array(4, input_manager
::TYPE_INT
, 4),
149 array('', input_manager
::TYPE_INT
, 0),
151 array(true, input_manager
::TYPE_FLAG
, true),
152 array(false, input_manager
::TYPE_FLAG
, true),
153 array(0, input_manager
::TYPE_FLAG
, true),
154 array('1', input_manager
::TYPE_FLAG
, true),
155 array('0', input_manager
::TYPE_FLAG
, true),
156 array('muhehe', input_manager
::TYPE_FLAG
, true),
158 array('C:\\WINDOWS\\user.dat', input_manager
::TYPE_PATH
, 'C:/WINDOWS/user.dat'),
159 array('D:\xampp\htdocs\24_integration/mdeploy.php', input_manager
::TYPE_PATH
, 'D:/xampp/htdocs/24_integration/mdeploy.php'),
160 array('d:/xampp/htdocs/24_integration/mdeploy.php', input_manager
::TYPE_PATH
, 'd:/xampp/htdocs/24_integration/mdeploy.php'),
161 array('../../../etc/passwd', input_manager
::TYPE_PATH
, '/etc/passwd'),
162 array('///////.././public_html/test.php', input_manager
::TYPE_PATH
, '/public_html/test.php'),
164 array("!@#$%|/etc/qwerty\n\n\t\n\r", input_manager
::TYPE_RAW
, "!@#$%|/etc/qwerty\n\n\t\n\r"),
166 array("\nrock'n'roll.mp3\t.exe", input_manager
::TYPE_FILE
, 'rocknroll.mp3.exe'),
168 array('http://localhost/moodle/dev/plugin.zip', input_manager
::TYPE_URL
, 'http://localhost/moodle/dev/plugin.zip'),
170 'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip',
171 input_manager
::TYPE_URL
,
172 'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip'
175 array('5e8d2ea4f50d154730100b1645fbad67', input_manager
::TYPE_MD5
, '5e8d2ea4f50d154730100b1645fbad67'),
180 * @expectedException invalid_option_exception
182 public function test_input_type_path_multiple_colons() {
183 $input = testable_input_manager
::instance();
184 $input->cast_value('C:\apache\log:file', input_manager
::TYPE_PATH
); // must throw exception
188 * @expectedException invalid_option_exception
190 public function test_input_type_path_invalid_drive_label() {
191 $input = testable_input_manager
::instance();
192 $input->cast_value('0:/srv/moodledata', input_manager
::TYPE_PATH
); // must throw exception
196 * @expectedException invalid_option_exception
198 public function test_input_type_path_invalid_colon() {
199 $input = testable_input_manager
::instance();
200 $input->cast_value('/var/www/moodle:2.5', input_manager
::TYPE_PATH
); // must throw exception
204 * @expectedException invalid_coding_exception
206 public function test_cast_array_argument() {
207 $input = testable_input_manager
::instance();
208 $input->cast_value(array(1, 2, 3), input_manager
::TYPE_INT
); // must throw exception
212 * @expectedException invalid_coding_exception
214 public function test_cast_object_argument() {
215 $input = testable_input_manager
::instance();
217 $input->cast_value($o, input_manager
::TYPE_INT
); // must throw exception
221 * @expectedException invalid_option_exception
223 public function test_cast_invalid_url_value() {
224 $input = testable_input_manager
::instance();
225 $invalid = 'file:///etc/passwd';
226 $input->cast_value($invalid, input_manager
::TYPE_URL
); // must throw exception
230 * @expectedException invalid_option_exception
232 public function test_cast_invalid_md5_value() {
233 $input = testable_input_manager
::instance();
234 $invalid = 'this is not a valid md5 hash';
235 $input->cast_value($invalid, input_manager
::TYPE_MD5
); // must throw exception
239 * @expectedException invalid_option_exception
241 public function test_cast_tilde_in_path() {
242 $input = testable_input_manager
::instance();
243 $invalid = '~/public_html/moodle_dev';
244 $input->cast_value($invalid, input_manager
::TYPE_PATH
); // must throw exception
247 public function test_has_option() {
248 $provider = input_fake_provider
::instance();
250 $provider->set_fake_options(array());
251 $this->assertFalse($provider->has_option('foo')); // foo not passed
253 $provider->set_fake_options(array('foo' => 1));
254 $this->assertFalse($provider->has_option('foo')); // foo passed but not a known option
256 $provider->set_fake_options(array('foo' => 1, 'help' => false));
257 $this->assertTrue($provider->has_option('help')); // help passed and it is a flag (value ignored)
258 $this->assertTrue($provider->has_option('h')); // 'h' is a shortname for 'help'
261 public function test_get_option() {
262 $input = testable_input_manager
::instance();
263 $provider = input_fake_provider
::instance();
265 $provider->set_fake_options(array('help' => false, 'passfile' => '_mdeploy.123456'));
266 $this->assertTrue($input->get_option('h'));
267 $this->assertEquals($input->get_option('passfile'), '_mdeploy.123456');
268 $this->assertEquals($input->get_option('password', 'admin123'), 'admin123');
270 $this->assertEquals($input->get_option('password'), 'admin123'); // must throw exception (not passed but required)
271 $this->assertTrue(false);
272 } catch (missing_option_exception
$e) {
273 $this->assertTrue(true);
277 public function test_moving_and_removing_directories() {
278 $worker = testable_worker
::instance();
280 $root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
281 mkdir($root.'/a', 0777, true);
282 touch($root.'/a/a.txt');
284 $this->assertTrue(file_exists($root.'/a/a.txt'));
285 $this->assertFalse(file_exists($root.'/b/a.txt'));
286 $this->assertTrue($worker->move_directory($root.'/a', $root.'/b'));
287 $this->assertFalse(is_dir($root.'/a'));
288 $this->assertTrue(file_exists($root.'/b/a.txt'));
289 $this->assertTrue($worker->move_directory($root.'/b', $root.'/c', true));
290 $this->assertTrue(file_exists($root.'/c/a.txt'));
291 $this->assertFalse(file_exists($root.'/b/a.txt'));
292 $this->assertTrue(is_dir($root.'/b'));
293 $this->assertTrue($worker->remove_directory($root.'/c', true));
294 $this->assertFalse(file_exists($root.'/c/a.txt'));
295 $this->assertTrue($worker->remove_directory($root.'/c'));
296 $this->assertFalse(is_dir($root.'/c'));
299 public function test_create_directory_precheck() {
300 $worker = testable_worker
::instance();
302 $root = sys_get_temp_dir().'/'.uniqid('mdeploytest', true);
303 $this->assertFalse(file_exists($root));
304 $this->assertTrue($worker->create_directory_precheck($root));
305 $this->assertFalse(file_exists($root)); // The precheck is supposed to remove it again.
309 * Test that an invalid setting throws an exception.
311 * @dataProvider get_env_unlisted_provider
312 * @expectedException invalid_setting_exception
313 * @expectedExceptionMessageRegExp /^Requested environment setting '[^']*' is invalid.$/
315 public function test_get_env_unlisted($key) {
316 $worker = testable_worker
::instance();
317 $worker->get_env($key);
320 public function get_env_unlisted_provider() {
322 // Completely invalid environment variables.
326 // Valid ones which have not been whitelisted.
327 array('noemailever'),
333 * Test that a valid, but unset setting throws an exception.
335 * @dataProvider get_env_valid_provider
336 * @expectedException invalid_setting_exception
337 * @expectedExceptionMessageRegExp /^Requested environment setting '[^']*' is not current set.$/
339 public function test_get_env_unset($key) {
340 // Ensure that the setting is currently unset.
344 $worker = testable_worker
::instance();
345 $worker->get_env($key);
349 * Test that a valid setting with data returns that data.
351 * @dataProvider get_env_valid_provider
353 public function test_get_env_valid($key) {
354 // Ensure that the setting is currently unset.
356 $CFG->$key = rand(0, 1000);
358 $worker = testable_worker
::instance();
359 $value = $worker->get_env($key);
361 $this->assertEquals($CFG->$key, $value);
364 public function get_env_valid_provider() {