-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
SqlSyncTest.php
185 lines (161 loc) · 8.63 KB
/
SqlSyncTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?php
namespace Unish;
/**
* @group slow
* @group commands
* @group sql
*/
class SqlSyncTest extends CommandUnishTestCase
{
public function testSimulatedSqlSync()
{
if ($this->isWindows()) {
$this->markTestSkipped('On Windows, Paths mismatch and confuse rsync.');
}
$fixtureSites = [
'remote' => [
'host' => 'server.isp.simulated',
'user' => 'www-admin',
'ssh' => [
'options' => '-o PasswordAuthentication=whatever'
],
'paths' => [
'drush-script' => '/path/to/drush',
],
],
'local' => [
],
];
$this->setUpSettings($fixtureSites, 'synctest');
$options = [
'uri' => 'OMIT',
'simulate' => null,
'alias-path' => __DIR__ . '/resources/alias-fixtures',
// @todo Ensure that shortcuts are normalized to long option names https://github.com/drush-ops/drush/pull/4515.
'verbose' => null,
];
$expectedAliasPath = '--alias-path=__DIR__/resources/alias-fixtures';
// Test simulated simple rsync remote-to-local
$this->drush('sql:sync', ['@synctest.remote', '@synctest.local'], $options, '@synctest.local');
$output = $this->getSimplifiedErrorOutput();
$this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-dump --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=remote --root=__DIR__/sut", $output);
$this->assertStringContainsString("[notice] Simulating: __DIR__/drush core-rsync @synctest.remote:/simulated/path/to/dump.tgz @synctest.local:__SANDBOX__/tmp/dump.tgz --yes --uri=local --root=__DIR__/sut -- --remove-source-files", $output);
$this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-query --no-interaction --strict=0 --file=__SANDBOX__/tmp/dump.tgz --file-delete --uri=local --root=__DIR__/sut", $output);
// Test simulated simple sql:sync local-to-remote
$this->drush('sql:sync', ['@synctest.local', '@synctest.remote'], $options, '@synctest.local');
$output = $this->getSimplifiedErrorOutput();
$this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-dump --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=local --root=__DIR__/sut", $output);
$this->assertStringContainsString("[notice] Simulating: __DIR__/drush core-rsync @synctest.local:/simulated/path/to/dump.tgz @synctest.remote:/tmp/dump.tgz --yes --uri=local --root=__DIR__/sut -- --remove-source-files", $output);
$this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-query --no-interaction --strict=0 --file=/tmp/dump.tgz --file-delete --uri=remote --root=__DIR__/sut'", $output);
// Test simulated remote invoke with a remote runner.
$this->drush('sql:sync', ['@synctest.remote', '@synctest.local'], $options, 'user@server/path/to/drupal#sitename');
$output = $this->getSimplifiedErrorOutput();
$this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=no user@server 'drush --no-interaction sql:sync @synctest.remote @synctest.local --uri=sitename --root=/path/to/drupal'", $output);
}
/**
* Covers the following responsibilities.
* - A user created on the source site is copied to the destination site.
* - The email address of the copied user is sanitized on the destination site.
*
* General handling of site aliases will be in sitealiasTest.php.
*/
public function testLocalSqlSync()
{
if ($this->dbDriver() == 'sqlite') {
$this->markTestSkipped('SQL Sync does not apply to SQLite.');
return;
}
$this->setUpDrupal(2, true);
return $this->localSqlSync();
}
public function localSqlSync()
{
$options = [
'yes' => null,
'uri' => 'OMIT',
];
$stage_options = [
'uri' => 'stage',
] + $options;
// Create a user in the staging site
$name = 'joe.user';
$mail = "joe.user@myhome.com";
// Add user fields and a test User.
$this->drush('pm-install', ['field,text,telephone,comment'], $stage_options + ['yes' => null]);
$this->drush('php-script', ['user_fields-D8', $name, $mail], $stage_options + ['script-path' => __DIR__ . '/resources',]);
// Copy stage to dev, and then sql:sanitize.
$sync_options = [
'yes' => null,
'uri' => 'OMIT',
// Test wildcards expansion from within sql-sync. Also avoid D8 persistent entity cache.
'structure-tables-list' => 'cache,cache*',
];
$this->drush('sql-sync', ['@sut.stage', '@sut.dev'], $sync_options);
$this->drush('sql-sanitize', [], ['yes' => null, 'uri' => 'dev',], '@sut.dev');
// Confirm that the sample user is unchanged on the staging site
$this->drush('user-information', [$name], $options + ['format' => 'json'], '@sut.stage');
$info = $this->getOutputFromJSON(2);
$this->assertEquals($mail, $info['mail'], 'Email address is unchanged on source site.');
$this->assertEquals($name, $info['name']);
// Get the unchanged pass.
$this->drush('user-information', [$name], $stage_options + ['field' => 'pass']);
$original_hashed_pass = $this->getOutput();
// Confirm that the sample user's email and password have been sanitized on the dev site
$this->drush('user-information', [$name], $options + ['fields' => 'uid,name,mail,pass', 'format' => 'json', 'yes' => null], '@sut.dev');
$info = $this->getOutputFromJSON(2);
$this->assertEquals("user+2@localhost.localdomain", $info['mail'], 'Email address was sanitized on destination site.');
$this->assertEquals($name, $info['name']);
$this->assertNotEquals($info['pass'], $original_hashed_pass);
// Copy stage to dev with --sanitize and a fixed sanitized email
$sync_options = [
'yes' => null,
'uri' => 'OMIT',
// Test wildcards expansion from within sql-sync. Also avoid D8 persistent entity cache.
'structure-tables-list' => 'cache,cache*',
];
$this->drush('sql-sync', ['@sut.stage', '@sut.dev'], $sync_options);
$this->drush('sql-sanitize', [], ['yes' => null, 'sanitize-email' => 'user@mysite.org', 'uri' => 'OMIT',], '@sut.dev');
// Confirm that the sample user's email address has been sanitized on the dev site
$this->drush('user-information', [$name], $options + ['yes' => null, 'format' => 'json'], '@sut.dev');
$info = $this->getOutputFromJSON(2);
$this->assertEquals('user@mysite.org', $info['mail'], 'Email address was sanitized (fixed email) on destination site.');
$this->assertEquals($name, $info['name']);
$fields = [
'field_user_email' => 'joe.user.alt@myhome.com',
'field_user_string' => 'Private info',
'field_user_string_long' => 'Really private info',
'field_user_text' => 'Super private info',
'field_user_text_long' => 'Super duper private info',
'field_user_text_with_summary' => 'Private',
];
// Assert that field DO NOT contain values.
foreach ($fields as $field_name => $value) {
$this->assertUserFieldContents($field_name, $value);
}
// Assert that field_user_telephone DOES contain "5555555555".
$this->assertUserFieldContents('field_user_telephone', '5555555555', true);
}
/**
* Assert that a field on the user entity does or does not contain a value.
*
* @param string $field_name
* The machine name of the field.
* @param string $value
* The field value.
* @param bool $should_contain
* Whether the field should contain the value. Defaults to false.
*/
public function assertUserFieldContents($field_name, $value, $should_contain = false)
{
$table = 'user__' . $field_name;
$column = $field_name . '_value';
$this->drush('sql-query', ["SELECT $column FROM $table LIMIT 1"], ['uri' => 'OMIT',], '@sut.dev');
$output = $this->getOutput();
$this->assertNotEmpty($output);
if ($should_contain) {
$this->assertStringContainsString($value, $output);
} else {
$this->assertStringNotContainsString($value, $output);
}
}
}