From 5a11bb32443805703a953743b265aa9c54e9c91f Mon Sep 17 00:00:00 2001 From: Lana Brindley Date: Wed, 15 Jan 2014 14:05:49 +1000 Subject: [PATCH] Added documentation Added initial draft of turbo-hipster docs. Change-Id: I3820f3fc9ede52218b4c055678b14267b6c92e92 --- doc/images/THTestResult.png | Bin 0 -> 46333 bytes doc/source/intro.rst | 323 +++++++++++++++++++++++++++++++++--- 2 files changed, 304 insertions(+), 19 deletions(-) create mode 100644 doc/images/THTestResult.png diff --git a/doc/images/THTestResult.png b/doc/images/THTestResult.png new file mode 100644 index 0000000000000000000000000000000000000000..846ec3e679e4e3d2f70bbaa57e4c05b2f7a9a0ac GIT binary patch literal 46333 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 literal 0 HcmV?d00001 diff --git a/doc/source/intro.rst b/doc/source/intro.rst index d3fb16d..d9b6b48 100644 --- a/doc/source/intro.rst +++ b/doc/source/intro.rst @@ -1,21 +1,55 @@ - :title:Introduction - -Turbo Hipster +Turbo-hipster ============= -Turbo Hipster is a gearman worker designed to run tests using zuul -as the gearman client. It is primarily aimed at running openstack -continuous integration tests against pre-existing datasets but can -be used to automate any tests with zuul. +Turbo-hipster works with the existing OpenStack code review system to +implement testing-related plugins. Historically, whenever code has been +written for Nova it has been tested against trivial datasets rather than +real data. This can mean that when users run the updated code on their +databases they can run into issues that were not found during testing. A +variety of real-world databases have been collected, anonymized, and added +to the database migration plugin used by turbo-hipster. Turbo-hipster is +integrated into the existing code review system, and automatically runs +tests against these larger test datasets. Turbo-hipster is specifically +designed to flag issues where changes to the database schema may not work +due to outliers in real datasets, and to identify situations where a +migration may take an unreasonable amount of time against a large database. -Overview --------- +.. note:: + Database anonymity is important, and can be very time consuming. + The databases used by turbo-hipster to test against are real-world databases + that have been anonymized with a database anonymization tool called Fuzzy + Happiness. Fuzzy Happiness takes markup in the sqlalchemy models file and + uses that to decide what values to anonymize, and how to do so. This feature + is still in development, and until it is complete turbo-hipster will not + report back to Zuul automatically. See the Release Notes for more detail. -The zuul server receives jobs from a trigger requesting particular -jobs/tests to be ran. Turbo Hipster is able to provide a worker for -each of those jobs or a subset and report the success/failure back to -zuul. zuul will then collate responses from multiple workers and -build a report. +Additionally, turbo-hipster has been designed to be extensible, so it is +possible to write other plugins to expand its capabilities. + +Turbo-hipster and Zuul +---------------------- + +Turbo-hipster is a Gearman worker. Zuul provides arguments that turbo- +hipster uses to check out the patch, perform the database testing, and then +report back with success or failure. Zuul allows you to specify which jobs +should be run against which projects. You can create a rule in Zuul for it +to select jobs that require testing against a database. Turbo-hipster will +then register as being able to complete that type of job. Gearman handles +the connection between Zuul and Turbo-Hipster, recognizing when a job +matches the rule, and passing it to turbo-hipster for testing. When turbo- +hipster receives the patchset for the job, it creates a virtual environment +to test it. The result of the test is sent back to Gearman as a json string, +which contains links to compiled logfiles. + +The simplified workflow for Turbo-Hipster: + +1. Registers as a worker against Zuul's Gearman server +2. Receives jobs from Zuul as they arrive +3. Checks out the patchset +4. Sets up a new virtual environment for testing +5. Loads in a representative subset of the available datasets +6. Runs the migration against each dataset, and checks the result +7. Reports the results to Zuul, using the Gearman protocol Typical workflow diagram ------------------------ @@ -111,9 +145,260 @@ is mostly there... If you know graphviz please help!** } -zuul integration ----------------- +Installation +============ -Explain how zuul triggers builds and gates etc and how turbo-hipster -responds to them. Most of this is in the zuul documentation so don't -duplicate. +Turbo-hipster is installed directly into your Python ``site-packages`` +directory, and is then run as a service. It is managed using a configuration +file, which is in .json format. + +Installing turbo-hipster +------------------------ + +1. Turbo-Hipster can be installed directly to your Python ``site-packages`` +directory:: + + $ sudo python setup.py install + +2. Copy the configuration file to a convenient location. By default, +turbo-hipster will look in ``/etc/turbo-hipster/config.json`` :: + + $ cp -R etc/turbo-hipster /etc/ + +3. The Turbo-Hipster configuration file is in .json format. Open the +``config.json`` configuration file in your preferred editor and modify it +for your environment:: + + **zuul_server** + A dictionary containing details about how to communicate + with zuul + **git_url** + The publicly accessible protocol and URI from where + to clone projects and zuul_ references from. For + example:: + http://review.openstack.org/p/ + or:: + git://review.example.org + **gearman_host** + The host of gearman_. zuul talks to its workers via + the gearman protocol and while it comes with a built- + in gearman server you can use a separate one. + **gearman_port** + The port that gearman listens on. + **debug_log** + A path to the debug log. Turbo-hipster will attempt to create + the file but must have write permissions. + **jobs_working_dir** + Each job will likely need to write out log and debug + information. This defines where turbo-hipster will do that. + **git_working_dir** + turbo-hipster needs to take a copy of the git tree of a + project to work from. This is the path it'll clone into and + work from (if needed). + **pip_download_cache** + Some of turbo-hipsters task plugins download requirements + for projects. This is the cache directory used by pip. + **plugins** + A list of enabled plugins and their settings in a dictionary. + The only required parameters are *name*, which should be the + same as the folder containing the plugin module, and + *function*, which is the function registered with zuul. + Any other parameters are specified by the plugin themselves + as required. + **publish_logs** + Log results from plugins can be published using multiple + methods. Currently only a local copy is fully implemented. + **type** + The type of protocol to copy the log to. eg 'local' + **path** + A type specific parameter defining the local location + destination. + **prepend_url** + What to prepend to the path when sending the result + URL back to zuul. This can be useful as you may want + to use a script to authenticate against a swift + account or to use *laughing_spice* to format the logs + etc. + +4. Create a turbo-hipster user: + + $ useradd turbo-hipster + +5. Create the directories listed in the configuration file, and give the +``turbo-hipster`` user write access:: + + $ mkdir -p /var/log/turbo-hipster/ + $ chown turbo-hipster:turbo-hipster /var/log/turbo-hipster/ + + $ mkdir -p /var/lib/turbo-hipster/jobs + $ chown turbo-hipster:turbo-hipster /var/lib/turbo-hipster/jobs + + $ mkdir -p /var/lib/turbo-hipster/git + $ chown turbo-hipster:turbo-hipster /var/lib/turbo-hipster/git + + $ mkdir -p /var/cache/pip + $ chown turbo-hipster:turbo-hipster /var/cache/pip + +6. Open the MySQL log rotation configuration file in your preferred text +editor, and edit it to ensure it is writable by ``other``:: + + $ vim /etc/logrotate.d/mysql-server + # edit create 640 to 644. + +.. note:: + The turbo-hipster source code is also available for download from + the `turbo-hipster github page `_ + + $ git clone https://github.com/rcbau/turbo-hipster + +Starting turbo-hipster +---------------------- + +Turbo-hipster can be run from the command line:: + + $ ./turbo-hipster/worker_server.py + +This option allows you to pass parameters to turbo-hipster. Use the --help +parameter to see a full list. + ++-------+--------------+--------------------------------------------------------+ +| Short | Long | Description | ++=======+==============+========================================================+ +| -c | --config | Print the path to the configuration file and exit | ++-------+--------------+--------------------------------------------------------+ +| -b | --background | Run as a daemon in the background | ++-------+--------------+--------------------------------------------------------+ +| -p | --pidfile | Specify the PID file to lock while running as a daemon | ++-------+--------------+--------------------------------------------------------+ + +Alternatively, you can start turbo-hipster as a service. + +1. Copy the turbo-hipster init.d script to /etc/init.d/: + + $ sudo cp etc/init.d/turbo-hipster /etc/init.d/ + +2. Reload the script with the default configuration: + + $ sudo update-rc.d turbo-hipster defaults + +3. Start the service: + + $ sudo service turbo-hipster start + +Plugins +======= + +Plugins can be used to extend turbo-hipster's capabilities. + +.. note:: + Currently, the only available plugin for turbo-hipster is the + Database Migration plugin, ``gate_real_db_upgrade``, which tests code + against a variety of real-world databases. + +Installing plugins +------------------ + +Turbo-hipster plugins are responsible for handling the jobs that are passed +to it. They must successfully build reports and publish them according to +their configuration. They must also be able to communicate test results back +to Zuul using Gearman. + +Plugins must take a standard format in order to be able to work correctly +with turbo-hipster. They must contain a ``task.py`` file with a ``Runner`` +class. + +Once you have created a turbo-hipster plugin, you need to configure it in +the ``config.json`` configuration file. + +.. FIXME More config information required here + +Plugin: Database migration with ``gate_real_db_upgrade`` +-------------------------------------------------------- + +The database migration plugin, ``gate_real_db_upgrade``, is used to test +datasets against real-world, anonymized, databases. + +Migrating a database +-------------------- + +In order to use turbo-hipster with the ``gate_real_db_upgrade`` plugin, you +need to set up the databases to test against, and point to the plugin in +turbo-hipster's configuration file. + +1. Create a directory for the datasets: + + $ mkdir -p /var/lib/turbo-hipster/datasets + +2. Copy the json dataset to the directory you created: + + $ cp /my/dataset.json /var/lib/turbo-hipster/datasets/ + +3. Open the ``/etc/turbo-hipster/config.json`` file in your preferred +editor, locate the plugins section, and add this line:: + + **plugins** + gate_real_db_upgrade + +Testing with turbo-hipster +========================== + +When turbo-hipster completes a test, it sends the result of the test back to +Gearman. These results contain a link to a compiled logfile for the test. + +If the test fails, or takes too long to complete, turbo-hipster will add a +review to your patchset that looks like this: + +.. image:: ../images/THTestResult.png + +Reading test reports +-------------------- + +An example of a standard log file: +http://thw01.rcbops.com/results/54/54202/5/check/gate-real-db-upgrade_nova_mysql_devstack_150/ddd6d53/20130910_devstack_applied_to_150.log + +An example of the same logfile, using the javascript logviewer: +http://thw01.rcbops.com/logviewer/?q=/results/54/54202/5/check/gate-real-db-upgrade_nova_mysql_devstack_150/ddd6d53/20130910_devstack_applied_to_150.log + +Test failure codes +------------------ + +This section gives a list of failure codes, including some steps you can +take for troubleshooting errors: + + FAILURE - Did not find the end of a migration after a start + +If you look at the log you should find that a migration began but never +finished. Hopefully there'll be a traceroute for you to follow through to +get some hints about why it failed. + + WARNING - Migration %s took too long + +In this case your migration took a long time to run against one of the test +datasets. You should reconsider what operations your migration is performing +and see if there are any optimizations you can make, or if it is really +necessary. If there is no way to speed up your migration you can email us at +rcbau@rcbops.com for an exception. + + FAILURE - Final schema version does not match expectation + +Somewhere along the line the migrations stopped and did not reach the +expected version. Our datasets start at previous releases and have to +upgrade all the way through to the most current release. If you see this, +inspect the log for traceroutes or other hints about the failure. + + FAILURE - Could not setup seed database. + FAILURE - Could not find seed database. + +These errors are internal errors. If you see either of these, contact us at +rcbau@rcbops.com to let us know so we can fix and rerun the tests for you. + + FAILURE - Could not import required module. + +This error probably shouldn't happen as Jenkins should catch it in the unit +tests before Turbo-Hipster launches. If you see this, please contact us at +rcbau@rcbops.com and let us know. + +If you receive an error that you think is a false positive, leave a comment +on the review with the sole contents of "recheck migrations". + +If you have any questions/problems please contact us at rcbau@rcbops.com. \ No newline at end of file