def test_cd_in_guest_context_manager(container): from burlap.openvz import guest with guest(container): with cd('/tmp'): run('touch bar') assert is_file('bar') assert is_file('/tmp/bar')
def _service_name(version=None): if is_file('/etc/init.d/postgresql'): return 'postgresql' if version and is_file('/etc/init.d/postgresql-%s' % version): return 'postgresql-%s' % version with cd('/etc/init.d'): with settings(hide('running', 'stdout')): return run('ls postgresql-*').splitlines()[0]
def _service_name(version=None): if is_file('/etc/init.d/postgresql'): return 'postgresql' if version and is_file('/etc/init.d/postgresql-%s' % version): return 'postgresql-%s' % version with cd('/etc/init.d'): with settings(hide('running', 'stdout')): return run('ls postgresql-*').splitlines()[0]
def test_install_and_uninstall_local_package(nodejs): from burlap.nodejs import install_package, package_version, uninstall_package if not package_version('underscore', local=True): install_package('underscore', version='1.4.2', local=True) assert is_file('node_modules/underscore/underscore.js') assert package_version('underscore', local=True) == '1.4.2' uninstall_package('underscore', local=True) assert package_version('underscore', local=True) is None assert not is_file('node_modules/underscore/underscore.js')
def test_install_and_uninstall_local_package(nodejs): from burlap.nodejs import install_package, package_version, uninstall_package if not package_version('underscore', local=True): install_package('underscore', version='1.4.2', local=True) assert is_file('node_modules/underscore/underscore.js') assert package_version('underscore', local=True) == '1.4.2' uninstall_package('underscore', local=True) assert package_version('underscore', local=True) is None assert not is_file('node_modules/underscore/underscore.js')
def locales(names): """ Require the list of locales to be available. Raises UnsupportedLocales if some of the required locales are not supported. """ family = distrib_family() if family == 'debian': command = 'dpkg-reconfigure --frontend=noninteractive locales' if distrib_id() == 'Ubuntu': config_file = '/var/lib/locales/supported.d/local' if not is_file(config_file): run_as_root('touch %s' % config_file) else: config_file = '/etc/locale.gen' _locales_generic(names, config_file=config_file, command=command) elif family in ['arch', 'gentoo']: _locales_generic(names, config_file='/etc/locale.gen', command='locale-gen') elif distrib_family() == 'redhat': _locales_redhat(names) else: raise UnsupportedFamily( supported=['debian', 'arch', 'gentoo', 'redhat'])
def template(name=None, url=None): """ Require an OpenVZ OS template. If the OS template is not installed yet, it will be downloaded from *url* using :py:func:`~burlap.openvz.download_template()`:: from burlap import require # Use custom OS template require.openvz.template(url='http://example.com/templates/mybox.tar.gz') If no *url* is provided, :py:func:`~burlap.openvz.download_template()` will attempt to download the OS template from the `download.openvz.org <http://download.openvz.org/template/precreated/>`_ repository:: from burlap import require # Use OS template from http://download.openvz.org/template/precreated/ require.openvz.template('debian-6.0-x86_64') """ if name is not None: filename = '%s.tar.gz' % name else: filename = os.path.basename(url) if not is_file(os.path.join('/var/lib/vz/template/cache', filename)): openvz.download_template(name, url)
def virtualenv_exists(directory): """ Check if a Python `virtual environment`_ exists. .. _virtual environment: http://www.virtualenv.org/ """ return is_file(posixpath.join(directory, 'bin', 'python'))
def test_install_and_uninstall_global_package(nodejs): from burlap.nodejs import install_package, package_version, uninstall_package # This is not in root's PATH on RedHat systems with path('/usr/local/bin'): if not package_version('underscore'): install_package('underscore', version='1.4.2') assert package_version('underscore') == '1.4.2' assert is_file('/usr/local/lib/node_modules/underscore/underscore.js') uninstall_package('underscore') assert package_version('underscore') is None assert not is_file('/usr/local/lib/node_modules/underscore/underscore.js')
def test_require_directory_in_guest_context_manager(container): from burlap.openvz import guest with guest(container): require_directory('/tmp/newdir') with cd('/tmp/newdir'): run('touch baz') assert is_file('/tmp/newdir/baz')
def test_install_redis_in_guest_context_manager(container): from burlap.openvz import guest from burlap.require.redis import VERSION, instance with guest(container): instance('test') assert is_file('/etc/redis/test.conf') assert run('echo PING | /opt/redis-%s/redis-cli' % VERSION) == 'PONG'
def test_install_and_uninstall_global_package(nodejs): from burlap.nodejs import install_package, package_version, uninstall_package # This is not in root's PATH on RedHat systems with path('/usr/local/bin'): if not package_version('underscore'): install_package('underscore', version='1.4.2') assert package_version('underscore') == '1.4.2' assert is_file('/usr/local/lib/node_modules/underscore/underscore.js') uninstall_package('underscore') assert package_version('underscore') is None assert not is_file( '/usr/local/lib/node_modules/underscore/underscore.js')
def test_tomcat_7_version(jdk): from burlap.require.tomcat import installed from burlap.tomcat import version, DEFAULT_VERSION installed() assert is_file(os.path.join(PATH, 'bin/catalina.sh')) assert version(PATH) == DEFAULT_VERSION
def test_require_jdk_version_6(): from burlap.oracle_jdk import version from burlap.require.oracle_jdk import installed installed('6u45-b06') assert is_file('/opt/jdk/bin/java') assert version() == '6u45-b06'
def test_require_default_jdk_version(): from burlap.oracle_jdk import version, DEFAULT_VERSION from burlap.require.oracle_jdk import installed installed() assert is_file('/opt/jdk/bin/java') assert version() == DEFAULT_VERSION
def test_install_debian_package_in_guest_context_manager(container): from burlap.deb import update_index from burlap.openvz import guest from burlap.require.deb import package as require_deb_package with guest(container): update_index() require_deb_package('htop') assert is_file('/usr/bin/htop')
def interfaces(): """ Get the list of network interfaces. Will return all datalinks on SmartOS. """ with settings(hide('running', 'stdout')): if is_file('/usr/sbin/dladm'): res = run('/usr/sbin/dladm show-link') else: res = sudo('/sbin/ifconfig -s') return map(lambda line: line.split(' ')[0], res.splitlines()[1:])
def distrib_desc(): """ Get the description of the Linux distribution. For example: ``Debian GNU/Linux 6.0.7 (squeeze)``. """ with settings(hide('running', 'stdout')): if not is_file('/etc/redhat-release'): return run('lsb_release --desc --short') return run('cat /etc/redhat-release')
def distrib_desc(): """ Get the description of the Linux distribution. For example: ``Debian GNU/Linux 6.0.7 (squeeze)``. """ with settings(hide('running', 'stdout')): if not is_file('/etc/redhat-release'): return run('lsb_release --desc --short') return run('cat /etc/redhat-release')
def test_tomcat_6_version(jdk): TOMCAT6_VERSION = '6.0.36' from burlap.require.tomcat import installed from burlap.tomcat import version installed(version=TOMCAT6_VERSION) assert is_file(os.path.join(PATH, 'bin/catalina.sh')) assert version(PATH) == TOMCAT6_VERSION
def test_require_python_package(venv): """ Test Python package installation """ from burlap import require import burlap with burlap.python.virtualenv(venv): require.python.package('fabric') assert is_file(posixpath.join(venv, 'bin/fab'))
def test_require_python_package(venv): """ Test Python package installation """ from burlap import require import burlap with burlap.python.virtualenv(venv): require.python.package('fabric') assert is_file(posixpath.join(venv, 'bin/fab'))
def test_callback_is_called_when_watched_file_is_modified(watched_file): from burlap.files import watch from burlap.require import file as require_file try: with watch('watched', callback=partial(require_file, 'modified1')): require_file('watched', contents='bbb') assert is_file('modified1') finally: run('rm -f modified1')
def test_callback_is_called_when_watched_file_is_modified(watched_file): from burlap.files import watch from burlap.require import file as require_file try: with watch('watched', callback=partial(require_file, 'modified1')): require_file('watched', contents='bbb') assert is_file('modified1') finally: run('rm -f modified1')
def test_callback_is_not_called_when_watched_file_is_not_modified(watched_file): from burlap.files import watch from burlap.require import file as require_file try: with watch('watched', callback=partial(require_file, 'modified2')): pass assert not is_file('modified2') finally: run('rm -f modified2')
def test_require_file_from_url(): """ Require that a file exists, whose contents should come from a URL """ from burlap.require import file as require_file try: require_file(url='http://www.google.com/robots.txt') assert is_file('robots.txt') finally: run('rm -f robots.txt')
def test_require_file_from_url(): """ Require that a file exists, whose contents should come from a URL """ from burlap.require import file as require_file try: require_file(url='http://www.google.com/robots.txt') assert is_file('robots.txt') finally: run('rm -f robots.txt')
def test_require_file(): """ Require that a file exists, whose contents should come from a URL """ from burlap.require import file as require_file try: require_file('foo') assert is_file('foo') assert run('cat foo') == '' finally: run('rm -f foo')
def installed_from_source(version=VERSION): """ Require Redis to be installed from source. The compiled binaries will be installed in ``/opt/redis-{version}/``. """ from burlap.require import directory as require_directory from burlap.require import file as require_file from burlap.require import user as require_user from burlap.require.deb import packages as require_deb_packages from burlap.require.rpm import packages as require_rpm_packages family = distrib_family() if family == 'debian': require_deb_packages([ 'build-essential', ]) elif family == 'redhat': require_rpm_packages([ 'gcc', 'make', ]) require_user('redis', home='/var/lib/redis', system=True) require_directory('/var/lib/redis', owner='redis', use_sudo=True) dest_dir = '/opt/redis-%(version)s' % locals() require_directory(dest_dir, use_sudo=True, owner='redis') if not is_file('%(dest_dir)s/redis-server' % locals()): with cd('/tmp'): # Download and unpack the tarball tarball = 'redis-%(version)s.tar.gz' % locals() url = _download_url(version) + tarball require_file(tarball, url=url) run('tar xzf %(tarball)s' % locals()) # Compile and install binaries with cd('redis-%(version)s' % locals()): run('make') for filename in BINARIES: run_as_root('cp -pf src/%(filename)s %(dest_dir)s/' % locals()) run_as_root('chown redis: %(dest_dir)s/%(filename)s' % locals())
def test_callback_is_not_called_when_watched_file_is_not_modified( watched_file): from burlap.files import watch from burlap.require import file as require_file try: with watch('watched', callback=partial(require_file, 'modified2')): pass assert not is_file('modified2') finally: run('rm -f modified2')
def test_require_file(): """ Require that a file exists, whose contents should come from a URL """ from burlap.require import file as require_file try: require_file('foo') assert is_file('foo') assert run('cat foo') == '' finally: run('rm -f foo')
def test_require_virtualenv(): """ Test Python virtualenv creation """ from burlap.require.python import virtualenv try: virtualenv('/tmp/venv') assert is_dir('/tmp/venv') assert is_file('/tmp/venv/bin/python') finally: run('rm -rf /tmp/venv')
def test_require_virtualenv(): """ Test Python virtualenv creation """ from burlap.require.python import virtualenv try: virtualenv('/tmp/venv') assert is_dir('/tmp/venv') assert is_file('/tmp/venv/bin/python') finally: run('rm -rf /tmp/venv')
def installed_from_source(version=VERSION): """ Require Redis to be installed from source. The compiled binaries will be installed in ``/opt/redis-{version}/``. """ from burlap.require import directory as require_directory from burlap.require import file as require_file from burlap.require import user as require_user from burlap.require.deb import packages as require_deb_packages from burlap.require.rpm import packages as require_rpm_packages family = distrib_family() if family == 'debian': require_deb_packages([ 'build-essential', ]) elif family == 'redhat': require_rpm_packages([ 'gcc', 'make', ]) require_user('redis', home='/var/lib/redis', system=True) require_directory('/var/lib/redis', owner='redis', use_sudo=True) dest_dir = '/opt/redis-%(version)s' % locals() require_directory(dest_dir, use_sudo=True, owner='redis') if not is_file('%(dest_dir)s/redis-server' % locals()): with cd('/tmp'): # Download and unpack the tarball tarball = 'redis-%(version)s.tar.gz' % locals() url = _download_url(version) + tarball require_file(tarball, url=url) run('tar xzf %(tarball)s' % locals()) # Compile and install binaries with cd('redis-%(version)s' % locals()): run('make') for filename in BINARIES: run_as_root('cp -pf src/%(filename)s %(dest_dir)s/' % locals()) run_as_root('chown redis: %(dest_dir)s/%(filename)s' % locals())
def configure_tomcat(path, overwrite=False): from fabric.contrib.files import append startup_script = """ #!/bin/sh ### BEGIN INIT INFO # Provides: tomcat # Required-Start: $local_fs $remote_fs $network $syslog $named # Required-Stop: $local_fs $remote_fs $network $syslog $named # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # X-Interactive: true # Short-Description: Tomcat # Description: Start Tomcat ### END INIT INFO case $1 in start) sh %(path)s/bin/startup.sh ;; stop) sh %(path)s/bin/shutdown.sh ;; restart) sh %(path)s/bin/shutdown.sh sh %(path)s/bin/startup.sh ;; esac exit 0""" % { 'path': path } # Check for existing files and overwrite. if is_file('/etc/init.d/tomcat'): if overwrite is False: raise OSError( "/etc/init.d/tomcat already exists and not overwriting.") else: run_as_root("rm -f /etc/init.d/tomcat") # Now create the file and symlinks. append('/etc/init.d/tomcat', startup_script, use_sudo=True) run_as_root('chmod 755 /etc/init.d/tomcat') if not is_link('/etc/rc1.d/K99tomcat'): run_as_root('ln -s /etc/init.d/tomcat /etc/rc1.d/K99tomcat') if not is_link('/etc/rc2.d/S99tomcat'): run_as_root('ln -s /etc/init.d/tomcat /etc/rc2.d/S99tomcat')
def test_require_file_from_string(): """ Require that a file exists, whose contents should be this string """ from burlap.require import file as require_file try: bar_contents = "This is the contents of the bar file" require_file('bar', contents=bar_contents) assert is_file('bar') assert run('cat bar') == bar_contents finally: run('rm -f bar')
def test_require_file_from_string(): """ Require that a file exists, whose contents should be this string """ from burlap.require import file as require_file try: bar_contents = "This is the contents of the bar file" require_file('bar', contents=bar_contents) assert is_file('bar') assert run('cat bar') == bar_contents finally: run('rm -f bar')
def sudoer(username, hosts="ALL", operators="ALL", passwd=False, commands="ALL"): """ Require sudo permissions for a given user. .. note:: This function can be accessed directly from the ``burlap.require`` module for convenience. """ tags = "PASSWD:" if passwd else "NOPASSWD:" spec = "%(username)s %(hosts)s=(%(operators)s) %(tags)s %(commands)s" %\ locals() filename = '/etc/sudoers.d/burlap-%s' % username if is_file(filename): run_as_root('chmod 0640 %(filename)s && rm -f %(filename)s' % locals()) run_as_root('echo "%(spec)s" >%(filename)s && chmod 0440 %(filename)s' % locals(), shell=True)
def configure_tomcat(path, overwrite=False): from fabric.contrib.files import append startup_script = """ #!/bin/sh ### BEGIN INIT INFO # Provides: tomcat # Required-Start: $local_fs $remote_fs $network $syslog $named # Required-Stop: $local_fs $remote_fs $network $syslog $named # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # X-Interactive: true # Short-Description: Tomcat # Description: Start Tomcat ### END INIT INFO case $1 in start) sh %(path)s/bin/startup.sh ;; stop) sh %(path)s/bin/shutdown.sh ;; restart) sh %(path)s/bin/shutdown.sh sh %(path)s/bin/startup.sh ;; esac exit 0""" % {'path': path} # Check for existing files and overwrite. if is_file('/etc/init.d/tomcat'): if overwrite is False: raise OSError("/etc/init.d/tomcat already exists and not overwriting.") else: run_as_root("rm -f /etc/init.d/tomcat") # Now create the file and symlinks. append('/etc/init.d/tomcat', startup_script, use_sudo=True) run_as_root('chmod 755 /etc/init.d/tomcat') if not is_link('/etc/rc1.d/K99tomcat'): run_as_root('ln -s /etc/init.d/tomcat /etc/rc1.d/K99tomcat') if not is_link('/etc/rc2.d/S99tomcat'): run_as_root('ln -s /etc/init.d/tomcat /etc/rc2.d/S99tomcat')
def test_install_dependencies_from_package_json_file(nodejs, testdir): from burlap.nodejs import install_dependencies, package_version, uninstall_package with cd(testdir): require_file('package.json', contents=json.dumps({ 'name': 'nodetest', 'version': '1.0.0', 'dependencies': { 'underscore': '1.4.2' } })) install_dependencies() assert is_file('node_modules/underscore/underscore.js') assert package_version('underscore', local=True) == '1.4.2' uninstall_package('underscore', local=True)
def ppa(name, auto_accept=True, keyserver=None): """ Require a `PPA`_ package source. Example:: from burlap import require # Node.js packages by Chris Lea require.deb.ppa('ppa:chris-lea/node.js', keyserver='my.keyserver.com') .. _PPA: https://help.launchpad.net/Packaging/PPA """ assert name.startswith('ppa:') user, repo = name[4:].split('/', 2) release = float(distrib_release()) if release >= 12.04: repo = repo.replace('.', '_') auto_accept = '--yes' if auto_accept else '' else: auto_accept = '' if not isinstance(keyserver, basestring) and keyserver: keyserver = keyserver[0] if keyserver: keyserver = '--keyserver ' + keyserver else: keyserver = '' distrib = distrib_codename() source = '/etc/apt/sources.list.d/%(user)s-%(repo)s-%(distrib)s.list' % locals( ) if not is_file(source): package('python-software-properties') run_as_root( 'add-apt-repository %(auto_accept)s %(keyserver)s %(name)s' % locals(), pty=False) update_index()
def last_update_time(): """ Get the time of last APT index update This is the last modification time of ``/var/lib/apt/periodic/burlap-update-success-stamp``. Returns ``-1`` if there was no update before. Example:: import burlap print(burlap.deb.last_update_time()) # 1377603808.02 """ STAMP = '/var/lib/apt/periodic/burlap-update-success-stamp' if not is_file(STAMP): return -1 return getmtime(STAMP)
def smartos_image(): """ Get the SmartOS image. Useful to determine the image/dataset for example. Returns None if it can't be determined. Example:: from burlap.pkg import smartos_image if smartos_image().startswith('percona'): sudo("mysql -uroot -psecretpassword -e 'show databases;'") """ with settings(hide('running', 'stdout')): if is_file('/etc/product'): return run( 'cat /etc/product | head -n 2 | tail -n 1 | awk \'{ print($2 " " $3 }\'' ) else: return None
def test_install_dependencies_from_package_json_file(nodejs, testdir): from burlap.nodejs import install_dependencies, package_version, uninstall_package with cd(testdir): require_file('package.json', contents=json.dumps({ 'name': 'nodetest', 'version': '1.0.0', 'dependencies': { 'underscore': '1.4.2' } })) install_dependencies() assert is_file('node_modules/underscore/underscore.js') assert package_version('underscore', local=True) == '1.4.2' uninstall_package('underscore', local=True)
def last_update_time(): """ Get the time of last APT index update This is the last modification time of ``/var/lib/apt/periodic/burlap-update-success-stamp``. Returns ``-1`` if there was no update before. Example:: import burlap print(burlap.deb.last_update_time()) # 1377603808.02 """ STAMP = '/var/lib/apt/periodic/burlap-update-success-stamp' if not is_file(STAMP): return -1 return getmtime(STAMP)
def distrib_id(): """ Get the OS distribution ID. Returns a string such as ``"Debian"``, ``"Ubuntu"``, ``"RHEL"``, ``"CentOS"``, ``"SLES"``, ``"Fedora"``, ``"Arch"``, ``"Gentoo"``, ``"SunOS"``... Example:: from burlap.system import distrib_id if distrib_id() != 'Debian': abort(u"Distribution is not supported") """ with settings(hide('running', 'stdout')): kernel = run('uname -s') if kernel == 'Linux': # lsb_release works on Ubuntu and Debian >= 6.0 # but is not always included in other distros if is_file('/usr/bin/lsb_release'): id_ = run('lsb_release --id --short') if id in ['arch', 'Archlinux' ]: # old IDs used before lsb-release 1.4-14 id_ = 'Arch' return id_ else: if is_file('/etc/debian_version'): return "Debian" elif is_file('/etc/fedora-release'): return "Fedora" elif is_file('/etc/arch-release'): return "Arch" elif is_file('/etc/redhat-release'): release = run('cat /etc/redhat-release') if release.startswith('Red Hat Enterprise Linux'): return "RHEL" elif release.startswith('CentOS'): return "CentOS" elif release.startswith('Scientific Linux'): return "SLES" elif is_file('/etc/gentoo-release'): return "Gentoo" elif kernel == "SunOS": return "SunOS"
def test_require_file_from_local_file(): """ Require that a file exists, whose contents should be this local file """ from burlap.require import file as require_file try: baz_contents = "This is the contents of the bar file" fd, filename = mkstemp() tmp_file = os.fdopen(fd, 'w') tmp_file.write(baz_contents) tmp_file.close() require_file('baz', source=filename) assert is_file('baz') assert run('cat baz') == baz_contents finally: os.remove(filename) run('rm -f baz')
def distrib_id(): """ Get the OS distribution ID. Returns a string such as ``"Debian"``, ``"Ubuntu"``, ``"RHEL"``, ``"CentOS"``, ``"SLES"``, ``"Fedora"``, ``"Arch"``, ``"Gentoo"``, ``"SunOS"``... Example:: from burlap.system import distrib_id if distrib_id() != 'Debian': abort(u"Distribution is not supported") """ with settings(hide('running', 'stdout')): kernel = run('uname -s') if kernel == 'Linux': # lsb_release works on Ubuntu and Debian >= 6.0 # but is not always included in other distros if is_file('/usr/bin/lsb_release'): id_ = run('lsb_release --id --short') if id in ['arch', 'Archlinux']: # old IDs used before lsb-release 1.4-14 id_ = 'Arch' return id_ else: if is_file('/etc/debian_version'): return "Debian" elif is_file('/etc/fedora-release'): return "Fedora" elif is_file('/etc/arch-release'): return "Arch" elif is_file('/etc/redhat-release'): release = run('cat /etc/redhat-release') if release.startswith('Red Hat Enterprise Linux'): return "RHEL" elif release.startswith('CentOS'): return "CentOS" elif release.startswith('Scientific Linux'): return "SLES" elif is_file('/etc/gentoo-release'): return "Gentoo" elif kernel == "SunOS": return "SunOS"
def ppa(name, auto_accept=True, keyserver=None): """ Require a `PPA`_ package source. Example:: from burlap import require # Node.js packages by Chris Lea require.deb.ppa('ppa:chris-lea/node.js', keyserver='my.keyserver.com') .. _PPA: https://help.launchpad.net/Packaging/PPA """ assert name.startswith('ppa:') user, repo = name[4:].split('/', 2) release = float(distrib_release()) if release >= 12.04: repo = repo.replace('.', '_') auto_accept = '--yes' if auto_accept else '' else: auto_accept = '' if not isinstance(keyserver, basestring) and keyserver: keyserver = keyserver[0] if keyserver: keyserver = '--keyserver ' + keyserver else: keyserver = '' distrib = distrib_codename() source = '/etc/apt/sources.list.d/%(user)s-%(repo)s-%(distrib)s.list' % locals() if not is_file(source): package('python-software-properties') run_as_root('add-apt-repository %(auto_accept)s %(keyserver)s %(name)s' % locals(), pty=False) update_index()
def locales(names): """ Require the list of locales to be available. Raises UnsupportedLocales if some of the required locales are not supported. """ family = distrib_family() if family == 'debian': command = 'dpkg-reconfigure --frontend=noninteractive locales' if distrib_id() == 'Ubuntu': config_file = '/var/lib/locales/supported.d/local' if not is_file(config_file): run_as_root('touch %s' % config_file) else: config_file = '/etc/locale.gen' _locales_generic(names, config_file=config_file, command=command) elif family in ['arch', 'gentoo']: _locales_generic(names, config_file='/etc/locale.gen', command='locale-gen') elif distrib_family() == 'redhat': _locales_redhat(names) else: raise UnsupportedFamily(supported=['debian', 'arch', 'gentoo', 'redhat'])
def test_redis_server_is_installed(redis): from burlap.require.redis import VERSION assert is_file('/opt/redis-%s/redis-server' % VERSION)
def test_nodejs_is_installed(nodejs): from burlap.nodejs import version, DEFAULT_VERSION assert is_file('/usr/local/bin/node') assert version() == DEFAULT_VERSION