Skip to content

Deal with existing database in test init script - #249

Merged
schlessera merged 12 commits into
wp-cli:masterfrom
tedsecretsource:228-simplify-test-rigging-creation
Feb 14, 2020
Merged

schlessera merged 12 commits into
wp-cli:masterfrom
tedsecretsource:228-simplify-test-rigging-creation

Conversation

@tedsecretsource

Copy link
Copy Markdown
Contributor

Fixed in issue in which the init script would fail if the database was already created. See #228 for details. I'm more than happy to write tests or whatever else is needed to get this in.

Fixed in issue in which the init script would fail if the database was already created.
@tedsecretsource
tedsecretsource requested a review from a team as a code owner January 24, 2020 15:01
Comment thread templates/install-wp-tests.sh Outdated
fi

# create database
mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA > /dev/null 2>&1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right solution! Dropping the database with no warning is going to cause problems for someone eventually.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought but isn't this script intended to be used to initialize the environment? I'm more than happy to make changes, including asking the user to confirm the deletion of the database prior to deleting it. Just let me know what seems reasonable.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asking the user to confirm the deletion of the database prior to deleting it

This seems reasonable to me but the best person to confirm is @schlessera

Added a condition to test for the existance of an existing DB, and then asking for permission before deleting it.
@schlessera schlessera added command:scaffold-plugin-tests Related to 'scaffold plugin-tests' command command:scaffold-theme-tests Related to 'scaffold theme-tests' command labels Jan 29, 2020

@schlessera schlessera left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread templates/install-wp-tests.sh Outdated
Make the confirmation on whether or not to drop the existing database test for fewer possibilities (just y, Y, yes, Yes, and mixed case equivalents).
@nylen

nylen commented Jan 30, 2020

Copy link
Copy Markdown

Just my opinion - you will want to get confirmation from @schlessera first:

This is heading in the right direction but it needs a few more fixes in order to work properly! It is also worth adding tests for the most common cases (db already exists, db doesn't exist)...

Comment thread templates/install-wp-tests.sh Outdated

# create database
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
if [ $(mysql -e 'show databases;' | grep ^$DB_NAME$) ]

@nylen nylen Jan 30, 2020 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command needs to use the --user="$DB_USER" --password="$DB_PASS"$EXTRA arguments for login.

Also, it is possible that the given MySQL user would have access to use the requested database, but not to list all databases. What should be done in this case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixing the missing creds now.

Comment thread templates/install-wp-tests.sh
Comment thread templates/install-wp-tests.sh Outdated
shopt -s nocasematch
if [[ $DELETE_EXISTING_DB =~ ^(y|yes)$ ]]
then
mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA > /dev/null 2>&1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this output being redirected to /dev/null? Shouldn't we show it instead, in case something goes wrong?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this context yes, we should show it. Changing that now too.

@tedsecretsource

Copy link
Copy Markdown
Contributor Author

Just my opinion - you will want to get confirmation from @schlessera first:

This is heading in the right direction but it needs a few more fixes in order to work properly! It is also worth adding tests for the most common cases (db already exists, db doesn't exist)...

Thanks for the feedback on what to test. I'm reading through the tests and learning how to run them now so it could be hours or days before I get another commit in incorporating your feedback but I really, really, really appreciate the feedback!

Added the missing credentials in the mysql call. Also changed the prompt in the drop db confirm to be something people are more used to seeing. Added an else case to handle instances in which the database doesn’t exists.
@tedsecretsource

tedsecretsource commented Jan 30, 2020 •

Copy link
Copy Markdown
Contributor Author

I'm still working on the tests but there are two things that I need input on.

  1. I've ended up duplicating the mysqladmin create db line (wrote some WET code). How bad is this in your view?
  2. I could probably solve this whole problem by adding set +e just before the mysqladmin create line and set -e just after it in the original version of the file to disable the script exiting on non-zero return statuses.

I think 2 is all that's needed because if the database already exists, that's ok. It's actually what we ultimately want (to have a database). It's even ok if MySQL returns an error when it tries to create it and fails because it already exists. We just don't want to stop execution of the rest of the script when that error occurs. Have I understood correctly the aim of this script and if so, does this make sense?

You'll also need to adapt the tests in https://github.com/wp-cli/scaffold-command/blob/master/features/install-wp-tests.feature

It seems this file is referenced in install-wp-tests.feature, scaffold-plugin-tests.feature and scaffold-theme-tests.feature. I'll have a look at those and see if they need reworking as well.

@schlessera

Copy link
Copy Markdown
Member

Regarding the issues you're currently facing, here's what I would look into...

Extract making a query out into a separate shell function. Something along these lines:

sql_query() {
	$(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA -e "$1")
}

This way, all requests use the same credentials.

Then, use an actual query to drop and to create the database instead of the mysqladmin. With a query, you can specify the optional IF NOT EXISTS` to only create if needed:

sql_query "CREATE DATABASE IF NOT EXISTS $DB_NAME"

However, I have to admit, I don't know whether this will be the exact same thing in terms of user capabilities. I assume so, but a quick google didn't help to know for sure.


In terms of tests, I think you only need to adapt the install-wp-tests.feature file. I assume that the other two only assert that the file was created, but don't run it.

@nylen

nylen commented Feb 4, 2020

Copy link
Copy Markdown

Then, use an actual query to drop and to create the database instead of the mysqladmin. With a query, you can specify the optional IF NOT EXISTS to only create if needed:

This will mean that the existing "skip-create-database" argument is not nearly as useful and might be worth removing entirely. It's also a more subtle change to the script's behavior: it will no longer fail / exit with a non-zero exit code when the database already exists.

Maybe not a big deal (hard to think of a case where this change would break something) but I think it is worth it to explicitly confirm that you're ok with the change here.

Fix an issue in which the mysql command line was not receiving or understanding the credentials being passed in
Add test for checking whether the database already exists, and how to handle it
@tedsecretsource

Copy link
Copy Markdown
Contributor Author

In the end I left the conditional, moist code as I originally wrote it (sans a minor improvement to the line that checks for the existence of the database). I think there is a lot of opportunity for refactoring but I think that's a separate task as it requires a bit more understanding of all the contexts this file is used in to be done properly.

I modified an existing scenario to test for the correct response when responding affirmatively to the "drop existing database" prompt. I do wonder if I should add a test for a negative response to the prompt???

Please let me know what else, if anything, you'd like me to address (and don't be afraid to insist if I need to take your suggestions, @schlessera, I'm still learning how this works…)

@tedsecretsource

Copy link
Copy Markdown
Contributor Author

I did want to respond to one aspect of this PR that I think should be different. I find the embedded if statements to be difficult to read / interpret. If you can live with executing a command that might return non-zero, the code could be simplified to:

# try to create the database
# if [ $? -gt 0 ]; then ask if we should drop the database and create it again; fi

This is a simplification of the code but I like the more direct approach: if the first command succeeds, just move along.

I guess I'm trying to understand where to draw the line between legibility and practicality. Any and all feedback is appreciated.

Simplified the condition for whether or not to recreate the database by moving the code into its own functions.
Modified one of the existing tests to test this feature. Specifically, this script should exit with return code 0, with text in both STDERR (the read prompt) and STDOUT (results of selected actions).
@tedsecretsource

Copy link
Copy Markdown
Contributor Author

You'll also need to adapt the tests in https://github.com/wp-cli/scaffold-command/blob/master/features/install-wp-tests.feature

Done, and I think I now understand the difference between run and try.

@schlessera schlessera left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with the code in its current state, but the "Leaving the database in place" needs to have a test as well.

When I run `WP_TESTS_DIR=/tmp/behat-wordpress-tests-lib phpunit -c {PLUGIN_DIR}/hello-world/phpunit.xml.dist`
Then the return code should be 0

When I try `WP_TESTS_DIR=/tmp/behat-wordpress-tests-lib WP_CORE_DIR=/tmp/behat-wordpress /usr/bin/env bash {PLUGIN_DIR}/hello-world/bin/install-wp-tests.sh wp_cli_test_scaffold wp_cli_test password1 localhost latest < affirmative-response`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also add another test with the path where the user would not affirm, to ensure that this will indeed abort the database drop.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with the code in its current state, but the "Leaving the database in place" needs to have a test as well.

Done. In all honesty, I feel like the tests are kind of superficial. For example, for the test to be robust, I should probably enter some data in the database, run the reinstall and respond NO to the prompt, and then test to see if the data is still in the database. Right now I'm just testing the output / logic in the script, not really the outcome of running it. Make sense?

Added a test with a negative response to the prompt to reinstall the database.

@schlessera schlessera left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor test string change, to make it clearer what is being tested AND test the DB name at the same time.

After that, we can merge this.

Comment thread features/install-wp-tests.feature Outdated
Comment thread features/install-wp-tests.feature Outdated
tedsecretsource and others added 3 commits February 13, 2020 19:05
Adding more of the expected output to the assertion to reduce the possibility of false positives.

Co-Authored-By: Alain Schlesser <alain.schlesser@gmail.com>
Adding more of the expected output to the assertion to reduce the possibility of false positives.

Co-Authored-By: Alain Schlesser <alain.schlesser@gmail.com>
Added parentheses around the database name in the test to make it match the actual output from the script.
@schlessera schlessera added this to the 2.0.9 milestone Feb 14, 2020
@schlessera
schlessera merged commit 8b34e4e into wp-cli:master Feb 14, 2020
@schlessera schlessera changed the title Fixed 228 - init script can be used repeatedly Deal with existing database in test init script Feb 14, 2020
@schlessera

Copy link
Copy Markdown
Member

Thanks for the PR, @tedsecretsource !

danielbachhuber pushed a commit that referenced this pull request Nov 18, 2022
…g-creation

Fixed 228 - init script can be used repeatedly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

command:scaffold-plugin-tests Related to 'scaffold plugin-tests' command command:scaffold-theme-tests Related to 'scaffold theme-tests' command

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants