Using Glusto¶
Using Glusto in a Module¶
To use Glusto in a module, import the Glusto class at the top of each module leveraging the glusto tools.
from glusto.core import Glusto as g
This provides access to all of the functionality of Glusto via the g
object
created by the import statement.
Using Glusto via the Python Interactive Interpreter¶
One of the primary objectives of Glusto is to maintain feature support from the Python Interactive Interpreter. Most, if not all, features should be easily referenced via the interpreter to ease use and reduce time during development.
To use Glusto via the Python Interactive Interpreter, enter the interpreter via
the python
command.
$ python >>> from glusto.core import Glusto as g
This provides access to all of the functionality of Glusto via the g.
object
created by the import statement–in the same way as imported in a script.
For example:
$ python >>> from glusto.core import Glusto as g >>> g.run_local('uname -a') (0, 'Linux mylaptop 4.4.9-300.fc23.x86_64 #1 SMP Wed May 4 23:56:27 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux\n', '') >>> config = g.load_config('examples/systems.yml') >>> config {'nodes': ['192.168.1.221', '192.168.1.222', '192.168.1.223', '192.168.1.224'], 'clients': ['192.168.1.225'], 'masternode': '192.168.1.221'} >>> g.run(config['nodes'][0], 'uname -a') (0, 'Linux rhserver1 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux\n', '') >>> g.list_ssh_connections() root@192.168.1.221 >>> g.run_serial(config['nodes'], 'hostname') {'192.168.1.224': (0, 'rhserver4\n', ''), \ '192.168.1.221': (0, 'rhserver1\n', ''), \ '192.168.1.223': (0, 'rhserver3\n', ''), \ '192.168.1.222': (0, 'rhserver2\n', '')} >>> g.list_ssh_connections() root@192.168.1.222 root@192.168.1.223 root@192.168.1.221 root@192.168.1.224
Typing from glusto.core import Glusto as g
each time you start the
interpreter can become tedious. To automatically run commands, the PYTHONSTARTUP
environment variable can be pointed to a python script containing common setup commands.
$ cat examples/pythonstartup_script.py from glusto.core import Glusto as g print "Python startup starting" config = g.load_config('examples/systems.yml') rcode, rout, rerr = g.run(config['nodes'][0], 'uname -a') print ('The uname info is: %s' % rout) print "Python startup complete"$ export PYTHONSTARTUP=examples/pythonstartup_script.py $ python Python 2.7.11 (default, Mar 31 2016, 20:46:51) [GCC 5.3.1 20151207 (Red Hat 5.3.1-2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. Python startup starting Python startup complete >>> g <class 'glusto.core.Glusto'> >>> config {'nodes': ['192.168.1.221', '192.168.1.222', '192.168.1.223', '192.168.1.224'], 'clients': ['192.168.1.225'], 'masternode': '192.168.1.221'} >>> uname_info 'Linux rhserver1 2.6.32-431.29.2.el6.x86_64 #1 SMP Sun Jul 27 15:55:46 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux\n'
Using the Glusto CLI Utility¶
Glusto provides a wrapper utility for features like unit test support, etc. Currently, the Glusto CLI allows leveraging the PyUnit, PyTest, and Nose module features in an easily configurable and callable wrapper.
To see the options available, use the --help
option.
$ /usr/bin/glusto --help Starting glusto via main() usage: glusto [-h] [-c CONFIG_LIST] [-u] [-d DISCOVER_DIR] Glusto CLI wrapper optional arguments: -h, --help show this help message and exit -c CONFIG_LIST, --config CONFIG_LIST Config file(s) to read. -u, --unittest Run unittests per provided config file. -d DISCOVER_DIR, --discover DISCOVER_DIR Discover unittests from directory -t RUN_PYTEST, --pytest RUN_PYTEST Run tests using the pytest framework -n RUN_NOSETESTS, --nosetests RUN_NOSETESTS Run tests using the nose framework
By default, the glusto
command will read the default config files in the /etc/glusto/
directory
For example, this run of the command reads the
defaults.yml
anddefaults.ini
files in/etc/glusto/
:$ glusto Starting glusto via main() defaults: {that: yada2, the_other: yada1 and yada2, this: yada1} globals: {some_default: yada yada} keyfile: ~/ssh/id_rsa log_color: true that: yada2 the_other: yada1 and yada2 this: yada1 use_controlpersist: true use_ssh: true Ending glusto via main()
Options for Running Unit Tests¶
To run unit tests via the Glusto CLI Utility, see the examples and links to additional documentation below.
Running PyUnit Tests¶
Example:
$ glusto -c 'examples/systems.yml' -u -d 'tests' $ glusto -c 'examples/unittests/unittest.yml examples/unittests/unittest_list.yml examples/systems.yml' -u
For more information on working with unit tests, see Unittests and Glusto
Running PyTest Tests¶
Example:
$ glusto -c 'examples/systems.yml' --pytest='-v -x tests -m response'
For more information on working with unit tests, see PyTest and Glusto
Running Nose Tests¶
Example:
$ glusto -c 'examples/systems.yml' --nosetests='-v -w tests'
For more information on working with unit tests, see Nose and Glusto
Running Different Frameworks in a Single Run¶
Not that the need would arise, but the capability to run all three in a single command is there.
Example running tests with
--pytest=
andnosetests=
options:$ glusto -c 'examples/systems.yml examples/unittests/unittest.yml' -u --nosetests='-w tests' --pytest='-x tests -m response' Starting glusto via main() clients: [192.168.1.225] masternode: 192.168.1.221 nodes: [192.168.1.221, 192.168.1.222, 192.168.1.223, 192.168.1.224] unittest: load_tests_from_module: {module_name: tests.test_glusto, use_load_tests: true} output_junit: false clients: [192.168.1.225] masternode: 192.168.1.221 nodes: [192.168.1.221, 192.168.1.222, 192.168.1.223, 192.168.1.224] unittest: load_tests_from_module: {module_name: tests.test_glusto, use_load_tests: true} output_junit: false PREFIX: tests.test_glusto.TestGlustoBasics Setting Up Class: TestGlustoBasics test_return_code (tests.test_glusto.TestGlustoBasics) Testing the return code ... Setting Up: tests.test_glusto.TestGlustoBasics.test_return_code Running: tests.test_glusto.TestGlustoBasics.test_return_code - Testing the return code Tearing Down: tests.test_glusto.TestGlustoBasics.test_return_code ok test_stdout (tests.test_glusto.TestGlustoBasics) Testing output to stdout ... Setting Up: tests.test_glusto.TestGlustoBasics.test_stdout Running: tests.test_glusto.TestGlustoBasics.test_stdout - Testing output to stdout Tearing Down: tests.test_glusto.TestGlustoBasics.test_stdout Cleaning up after setup on fail or after teardown ok test_stderr (tests.test_glusto.TestGlustoBasics) Testing output to stderr ... Setting Up: tests.test_glusto.TestGlustoBasics.test_stderr Running: tests.test_glusto.TestGlustoBasics.test_stderr - Testing output to stderr Tearing Down: tests.test_glusto.TestGlustoBasics.test_stderr ok test_expected_fail (tests.test_glusto.TestGlustoBasics) Testing an expected failure. This test should fail ... Setting Up: tests.test_glusto.TestGlustoBasics.test_expected_fail Running: tests.test_glusto.TestGlustoBasics.test_expected_fail - Testing an expected failure. This test should fail expected failure Tearing Down: tests.test_glusto.TestGlustoBasics.test_expected_fail test_negative_test (tests.test_glusto.TestGlustoBasics) Testing an expected failure as negative test ... Setting Up: tests.test_glusto.TestGlustoBasics.test_negative_test Running: tests.test_glusto.TestGlustoBasics.test_negative_test - Testing an expected failure as negative test Tearing Down: tests.test_glusto.TestGlustoBasics.test_negative_test ok test_skip_me (tests.test_glusto.TestGlustoBasics) Testing the unittest skip feature ... skipped 'Example test skip' Tearing Down Class: TestGlustoBasics ---------------------------------------------------------------------- Ran 6 tests in 0.585s OK (skipped=1, expected failures=1) pytest: -x tests -m response ==================================================================================== test session starts ===================================================================================== platform linux2 -- Python 2.7.11, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 rootdir: glusto, inifile: collected 21 items tests/test_glusto_pytest.py ... =========================================================================== 18 tests deselected by "-m 'response'" =========================================================================== ========================================================================== 3 passed, 18 deselected in 0.32 seconds =========================================================================== nosetests: -w tests /usr/lib64/python2.7/unittest/case.py:378: RuntimeWarning: TestResult has no addExpectedFailure method, reporting as passes RuntimeWarning) ...S..E...F.....E...... ====================================================================== ERROR: Load tests in a specific order. ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) TypeError: load_tests() takes exactly 3 arguments (0 given) ====================================================================== ERROR: Load tests in a specific order. ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) TypeError: load_tests() takes exactly 3 arguments (0 given) ====================================================================== FAIL: Testing an expected failure. This test should fail ---------------------------------------------------------------------- Traceback (most recent call last): File "glusto/tests/test_glusto_pytest.py", line 98, in test_expected_fail self.assertEqual(rcode, 0) AssertionError: 1 != 0 -------------------- >> begin captured stdout << --------------------- Setting Up: tests.test_glusto_pytest.TestGlustoBasicsPyTest.test_expected_fail Running: tests.test_glusto_pytest.TestGlustoBasicsPyTest.test_expected_fail - Testing an expected failure. This test should fail --------------------- >> end captured stdout << ---------------------- -------------------- >> begin captured logging << -------------------- plumbum.local: DEBUG: Running ['/usr/bin/ssh', '-T', '-oPasswordAuthentication=no', '-oStrictHostKeyChecking=no', '-oPort=22', '-oConnectTimeout=10', '-oControlMaster=auto', '-oControlPersist=4h', '-oControlPath=~/.ssh/glusto-ssh-%r@%h:%p', 'root@192.168.1.221', 'cd', '/root', '&&', 'false'] --------------------- >> end captured logging << --------------------- ---------------------------------------------------------------------- Ran 23 tests in 1.964s FAILED (SKIP=1, errors=2, failures=1) Ending glusto via main()
Note
I’ll be able to demonstrate this better when I have PyTest example test scripts written. The above command runs the same PyUnit-based test scripts against the PyUnit, PyTest and Nose frameworks.