aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2013-04-10 09:58:42 -0700
committerBryn M. Reeves <bmr@redhat.com>2013-04-10 09:58:42 -0700
commit3ecd2e7413f2bfc6ce35bcc510fc182772f8849c (patch)
tree89ddf1fe83492cf3d537121da9da2bc483e4ca29
parent77b62899401d6bda00ff79439e1394c47480b740 (diff)
parent662ec0cf85c291f5fb748887e48aba5d4e7e2b67 (diff)
downloadsos-3ecd2e7413f2bfc6ce35bcc510fc182772f8849c.tar.gz
Merge pull request #118 from battlemidget/unittest-fixes-1
Fix unittests and more pep8 conforming
-rw-r--r--.travis.yml18
-rw-r--r--AUTHORS4
-rw-r--r--Makefile4
-rw-r--r--README.md (renamed from README)20
-rw-r--r--sos.spec2
-rw-r--r--sos/plugins/__init__.py4
-rw-r--r--sos/plugins/abrt.py2
-rw-r--r--sos/plugins/acpid.py6
-rw-r--r--sos/plugins/amd.py2
-rw-r--r--sos/plugins/anaconda.py2
-rw-r--r--sos/plugins/apache.py6
-rw-r--r--sos/plugins/apparmor.py2
-rw-r--r--sos/plugins/apport.py2
-rw-r--r--sos/plugins/auditd.py2
-rw-r--r--sos/plugins/autofs.py6
-rw-r--r--sos/plugins/bootloader.py2
-rw-r--r--sos/plugins/ceph.py2
-rw-r--r--sos/plugins/cgroups.py6
-rw-r--r--sos/plugins/cloudforms.py2
-rw-r--r--sos/plugins/cluster.py2
-rw-r--r--sos/plugins/cobbler.py6
-rw-r--r--sos/plugins/ipa.py2
-rw-r--r--sos/plugins/iscsi.py4
-rw-r--r--sos/plugins/xen.py2
-rw-r--r--sos/plugins/xinetd.py2
-rw-r--r--sos/plugins/yum.py2
-rw-r--r--sos/utilities.py5
-rw-r--r--tests/plugin_tests.py26
28 files changed, 92 insertions, 53 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..fafcbd3d
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: python
+python:
+ - 2.7
+ - 3.2
+ - 3.3
+ - "pypy"
+matrix:
+ allow_failures:
+ - python: 3.2
+ - python: 3.3
+notifications:
+ email: false
+install:
+ - "pip install nose nose-cov --use-mirrors"
+ - "make gpgkey"
+ - "DESTDIR=. make install"
+script:
+ - "make test"
diff --git a/AUTHORS b/AUTHORS
index 1973fc98..d90785fb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,6 @@
-Adam Stokes <astokes@redhat.com>
+Adam Stokes <adam.stokes@ubuntu.com>
Ben Turner <bturner@redhat.com>
+Eric Williams <eric.williams@canonical.com>
Eugene Teo <eteo@redhat.com>
Gary Kotton <gkotton@redhat.com>
Jesse Jaggars <jjaggars@redhat.com>
@@ -8,6 +9,7 @@ John Berninger <jwb@redhat.com>
Justin Payne <jpayne@redhat.com>
Keith Kearnan <kearnan_keith@emc.com>
Kent Lamb <klamb@redhat.com>
+Louis Bouchard <louis.bouchard@canonical.com>
Marc Sauton <msauton@redhat.com>
Navid Sheikhol-Eslami <navid@redhat.com>
Pierre Amadio <pamadio@redhat.com>
diff --git a/Makefile b/Makefile
index ead90f52..68557a82 100644
--- a/Makefile
+++ b/Makefile
@@ -48,7 +48,7 @@ install: updateversion
install -m755 sosreport $(DESTDIR)/usr/sbin/sosreport
install -m644 sosreport.1.gz $(DESTDIR)/usr/share/man/man1/.
install -m644 sos.conf.5.gz $(DESTDIR)/usr/share/man/man5/.
- install -m644 LICENSE README $(DESTDIR)/usr/share/$(NAME)/.
+ install -m644 LICENSE README.md $(DESTDIR)/usr/share/$(NAME)/.
install -m644 $(NAME).conf $(DESTDIR)/etc/$(NAME).conf
install -m644 gpgkeys/$(GPG_TPL)support.pub $(DESTDIR)/usr/share/$(NAME)/.
for d in $(SUBDIRS); do make DESTDIR=`cd $(DESTDIR); pwd` -C $$d install; [ $$? = 0 ] || exit 1; done
@@ -58,7 +58,7 @@ updateversion:
$(NAME)-$(VERSION).tar.gz: clean gpgkey
@mkdir -p $(ARCHIVE_DIR)
- @tar -cv sosreport sos doc man po sos.conf LICENSE README sos.spec Makefile | tar -x -C $(ARCHIVE_DIR)
+ @tar -cv sosreport sos doc man po sos.conf LICENSE README.md sos.spec Makefile | tar -x -C $(ARCHIVE_DIR)
@mkdir -p $(ARCHIVE_DIR)/gpgkeys
@cp gpgkeys/$(GPG_TPL)support.pub $(ARCHIVE_DIR)/gpgkeys/.
@tar Ccvzf $(DIST_BUILD_DIR) $(DIST_BUILD_DIR)/$(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION)
diff --git a/README b/README.md
index b811e46b..dfbe0476 100644
--- a/README
+++ b/README.md
@@ -1,3 +1,5 @@
+[![Build Status](https://travis-ci.org/battlemidget/sosreport.png?branch=master)](https://travis-ci.org/battlemidget/sosreport)
+
This set of tools is designed to provide information to support organizations
in an extensible manner, allowing third parties, package maintainers, and
anyone else to provide plugins that will collect and report information that
@@ -8,15 +10,31 @@ version, to contribute, and for more information, please visit there.
To access to the public source code repository for this project run:
- git clone git://github.com/sosreport/sosreport.git
+```
+git clone git://github.com/sosreport/sosreport.git
+```
+
+### Manual Installation ###
+```
to install locally (as root) ==> make install
to build an rpm ==> make rpm
to build a deb ==> make deb-unsign
to build a zipfile for use with jython ==> make zip
+```
+
+### Pre-built Packaging ###
+
+Fedora/RHEL users install via yum:
+
+```
+yum install sos
+```
Debian/Ubuntu users can install via PPA:
+```
sudo add-apt-repository ppa:debugmonkeys/sosreport
sudo apt-get update
sudo apt-get install sos
+```
diff --git a/sos.spec b/sos.spec
index 2f1044f4..9baffb3b 100644
--- a/sos.spec
+++ b/sos.spec
@@ -44,7 +44,7 @@ rm -rf ${RPM_BUILD_ROOT}
%{python_sitelib}/*
%{_mandir}/man1/*
%{_mandir}/man5/*
-%doc README LICENSE
+%doc README.md LICENSE
%config(noreplace) %{_sysconfdir}/sos.conf
%changelog
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
index 6df08fc9..b0e3ab3f 100644
--- a/sos/plugins/__init__.py
+++ b/sos/plugins/__init__.py
@@ -140,8 +140,8 @@ class Plugin(object):
self.must_exit = False
- self.soslog = self.commons['soslog']
- self.proflog = self.commons['proflog']
+ self.soslog = self.commons['soslog'] if self.commons.has_key('soslog') else logging.getLogger('sos')
+ self.proflog = self.commons['proflog'] if self.commons.has_key('proflog') else logging.getLogger('sosprofile')
# get the option list into a dictionary
for opt in self.option_list:
diff --git a/sos/plugins/abrt.py b/sos/plugins/abrt.py
index 3e5bdeb0..9437c562 100644
--- a/sos/plugins/abrt.py
+++ b/sos/plugins/abrt.py
@@ -17,7 +17,7 @@
from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class abrt(Plugin, RedHatPlugin):
+class Abrt(Plugin, RedHatPlugin):
"""ABRT log dump
"""
diff --git a/sos/plugins/acpid.py b/sos/plugins/acpid.py
index c49da2d3..9a2d1236 100644
--- a/sos/plugins/acpid.py
+++ b/sos/plugins/acpid.py
@@ -14,10 +14,10 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
-class acpid(Plugin):
+class Acpid(Plugin):
plugin_name = "acpid"
-class RedHatAcpid(acpid, RedHatPlugin):
+class RedHatAcpid(Acpid, RedHatPlugin):
"""acpid related information
"""
def setup(self):
@@ -25,7 +25,7 @@ class RedHatAcpid(acpid, RedHatPlugin):
"/var/log/acpid*",
"/etc/acpi/events/power.conf"])
-class DebianAcpid(acpid, DebianPlugin, UbuntuPlugin):
+class DebianAcpid(Acpid, DebianPlugin, UbuntuPlugin):
"""acpid related information for Debian and Ubuntu
"""
def setup(self):
diff --git a/sos/plugins/amd.py b/sos/plugins/amd.py
index 11c8735d..4ecb8f54 100644
--- a/sos/plugins/amd.py
+++ b/sos/plugins/amd.py
@@ -16,7 +16,7 @@
from sos.plugins import Plugin, RedHatPlugin
-class amd(Plugin, RedHatPlugin):
+class Amd(Plugin, RedHatPlugin):
"""Amd automounter information
"""
files = ('/etc/rc.d/init.d/amd',)
diff --git a/sos/plugins/anaconda.py b/sos/plugins/anaconda.py
index 2a6d9983..dd5f9760 100644
--- a/sos/plugins/anaconda.py
+++ b/sos/plugins/anaconda.py
@@ -15,7 +15,7 @@
from sos.plugins import Plugin, RedHatPlugin
import os
-class anaconda(Plugin, RedHatPlugin):
+class Anaconda(Plugin, RedHatPlugin):
"""Anaconda / Installation information
"""
diff --git a/sos/plugins/apache.py b/sos/plugins/apache.py
index 0076534f..d889125a 100644
--- a/sos/plugins/apache.py
+++ b/sos/plugins/apache.py
@@ -14,14 +14,14 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
-class apache(Plugin):
+class Apache(Plugin):
"""Apache related information
"""
plugin_name = "apache"
option_list = [("log", "gathers all apache logs", "slow", False)]
-class RedHatApache(apache, RedHatPlugin):
+class RedHatApache(Apache, RedHatPlugin):
"""Apache related information for Red Hat distributions
"""
files = ('/etc/httpd/conf/httpd.conf',)
@@ -38,7 +38,7 @@ class RedHatApache(apache, RedHatPlugin):
if self.get_option("log"):
self.add_copy_spec("/var/log/httpd/*")
-class DebianApache(apache, DebianPlugin, UbuntuPlugin):
+class DebianApache(Apache, DebianPlugin, UbuntuPlugin):
"""Apache related information for Debian distributions
"""
files = ('/etc/apache2/apache2.conf',)
diff --git a/sos/plugins/apparmor.py b/sos/plugins/apparmor.py
index cae61c19..29ea02a9 100644
--- a/sos/plugins/apparmor.py
+++ b/sos/plugins/apparmor.py
@@ -15,7 +15,7 @@
from sos.plugins import Plugin, UbuntuPlugin
-class apparmor(Plugin, UbuntuPlugin):
+class Apparmor(Plugin, UbuntuPlugin):
"""Apparmor related information
"""
def setup(self):
diff --git a/sos/plugins/apport.py b/sos/plugins/apport.py
index 7ae319cc..f565261d 100644
--- a/sos/plugins/apport.py
+++ b/sos/plugins/apport.py
@@ -15,7 +15,7 @@
from sos.plugins import Plugin, DebianPlugin, UbuntuPlugin
-class apport(Plugin, DebianPlugin, UbuntuPlugin):
+class Apport(Plugin, DebianPlugin, UbuntuPlugin):
"""apport information
"""
def setup(self):
diff --git a/sos/plugins/auditd.py b/sos/plugins/auditd.py
index 41bd8605..27dda2ba 100644
--- a/sos/plugins/auditd.py
+++ b/sos/plugins/auditd.py
@@ -14,7 +14,7 @@
from sos.plugins import Plugin, RedHatPlugin
-class auditd(Plugin, RedHatPlugin):
+class Auditd(Plugin, RedHatPlugin):
"""Auditd related information
"""
diff --git a/sos/plugins/autofs.py b/sos/plugins/autofs.py
index ce529bb9..f88d4f8b 100644
--- a/sos/plugins/autofs.py
+++ b/sos/plugins/autofs.py
@@ -17,7 +17,7 @@
from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin, DebianPlugin
import os, re
-class autofs(Plugin):
+class Autofs(Plugin):
"""autofs server-related information
"""
@@ -53,14 +53,14 @@ class autofs(Plugin):
if self.checkdebug():
self.add_copy_spec(self.getdaemondebug())
-class RedHatAutofs(autofs, RedHatPlugin):
+class RedHatAutofs(Autofs, RedHatPlugin):
"""autofs server-related on RedHat based distributions"""
def setup(self):
super(RedHatAutofs, self).setup()
self.add_cmd_output("rpm -qV autofs")
-class DebianAutofs(autofs, DebianPlugin, UbuntuPlugin):
+class DebianAutofs(Autofs, DebianPlugin, UbuntuPlugin):
"""autofs server-related on Debian based distributions"""
def setup(self):
diff --git a/sos/plugins/bootloader.py b/sos/plugins/bootloader.py
index ead4c8ae..3b3d2124 100644
--- a/sos/plugins/bootloader.py
+++ b/sos/plugins/bootloader.py
@@ -14,7 +14,7 @@
from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin
-class bootloader(Plugin, RedHatPlugin, UbuntuPlugin):
+class Bootloader(Plugin, RedHatPlugin, UbuntuPlugin):
"""Bootloader information
"""
def setup(self):
diff --git a/sos/plugins/ceph.py b/sos/plugins/ceph.py
index 52668c26..fbcee784 100644
--- a/sos/plugins/ceph.py
+++ b/sos/plugins/ceph.py
@@ -14,7 +14,7 @@
from sos.plugins import Plugin, RedHatPlugin, UbuntuPlugin
-class ceph(Plugin, RedHatPlugin, UbuntuPlugin):
+class Ceph(Plugin, RedHatPlugin, UbuntuPlugin):
"""information on CEPH
"""
option_list = [("log", "gathers all ceph logs", "slow", False)]
diff --git a/sos/plugins/cgroups.py b/sos/plugins/cgroups.py
index 72344c2f..1027c04e 100644
--- a/sos/plugins/cgroups.py
+++ b/sos/plugins/cgroups.py
@@ -14,13 +14,13 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
-class cgroups(Plugin):
+class Cgroups(Plugin):
"""cgroup subsystem information
"""
plugin_name = "cgroups"
-class DebianCgroups(cgroups, DebianPlugin, UbuntuPlugin):
+class DebianCgroups(Cgroups, DebianPlugin, UbuntuPlugin):
files = ('/proc/cgroups',)
@@ -29,7 +29,7 @@ class DebianCgroups(cgroups, DebianPlugin, UbuntuPlugin):
"/sys/fs/cgroup"])
return
-class RedHatCgroups(cgroups, RedHatPlugin):
+class RedHatCgroups(Cgroups, RedHatPlugin):
"""Red Hat specific cgroup subsystem information
"""
diff --git a/sos/plugins/cloudforms.py b/sos/plugins/cloudforms.py
index 7027c96d..3a11cc42 100644
--- a/sos/plugins/cloudforms.py
+++ b/sos/plugins/cloudforms.py
@@ -16,7 +16,7 @@
from sos.plugins import Plugin, RedHatPlugin
import os
-class cloudforms(Plugin, RedHatPlugin):
+class Cloudforms(Plugin, RedHatPlugin):
"""CloudForms related information
"""
diff --git a/sos/plugins/cluster.py b/sos/plugins/cluster.py
index 7b169bd3..07eeb458 100644
--- a/sos/plugins/cluster.py
+++ b/sos/plugins/cluster.py
@@ -16,7 +16,7 @@ from sos.plugins import Plugin, RedHatPlugin
import os, re
from glob import glob
-class cluster(Plugin, RedHatPlugin):
+class Cluster(Plugin, RedHatPlugin):
"""cluster suite and GFS related information
"""
diff --git a/sos/plugins/cobbler.py b/sos/plugins/cobbler.py
index 3d8c9faf..e3d289e2 100644
--- a/sos/plugins/cobbler.py
+++ b/sos/plugins/cobbler.py
@@ -14,10 +14,10 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
-class cobbler(Plugin):
+class Cobbler(Plugin):
plugin_name = "cobbler"
-class RedHatCobbler(cobbler, RedHatPlugin):
+class RedHatCobbler(Cobbler, RedHatPlugin):
"""cobbler related information
"""
@@ -29,7 +29,7 @@ class RedHatCobbler(cobbler, RedHatPlugin):
self.add_copy_spec("/var/lib/rhn/kickstarts")
self.add_copy_spec("/var/lib/cobbler")
-class DebianCobbler(cobbler, DebianPlugin, UbuntuPlugin):
+class DebianCobbler(Cobbler, DebianPlugin, UbuntuPlugin):
"""cobbler related information for Debian and Ubuntu
"""
diff --git a/sos/plugins/ipa.py b/sos/plugins/ipa.py
index 293ebe28..1adbe162 100644
--- a/sos/plugins/ipa.py
+++ b/sos/plugins/ipa.py
@@ -17,7 +17,7 @@
from sos.plugins import Plugin, RedHatPlugin
from os.path import exists
-class ipa(Plugin, RedHatPlugin):
+class Ipa(Plugin, RedHatPlugin):
"""IPA diagnostic information
"""
diff --git a/sos/plugins/iscsi.py b/sos/plugins/iscsi.py
index 3d5423b8..22e37bd7 100644
--- a/sos/plugins/iscsi.py
+++ b/sos/plugins/iscsi.py
@@ -15,13 +15,13 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
-class iscsi(Plugin):
+class Iscsi(Plugin):
"""iscsi-initiator related information
"""
plugin_name = "iscsi"
-class RedHatIscsi(iscsi, RedHatPlugin):
+class RedHatIscsi(Iscsi, RedHatPlugin):
"""iscsi-initiator related information Red Hat based distributions
"""
diff --git a/sos/plugins/xen.py b/sos/plugins/xen.py
index 2a70a905..0a5684fa 100644
--- a/sos/plugins/xen.py
+++ b/sos/plugins/xen.py
@@ -17,7 +17,7 @@ import os
import re
from stat import *
-class xen(Plugin, RedHatPlugin):
+class Xen(Plugin, RedHatPlugin):
"""Xen related information
"""
def determine_xen_host(self):
diff --git a/sos/plugins/xinetd.py b/sos/plugins/xinetd.py
index 5c76bd1c..0a8833e8 100644
--- a/sos/plugins/xinetd.py
+++ b/sos/plugins/xinetd.py
@@ -17,7 +17,7 @@
from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin
import os
-class xinetd(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin):
+class Xinetd(Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin):
"""xinetd information
"""
diff --git a/sos/plugins/yum.py b/sos/plugins/yum.py
index 6f44fe42..d691c43c 100644
--- a/sos/plugins/yum.py
+++ b/sos/plugins/yum.py
@@ -15,7 +15,7 @@
from sos.plugins import Plugin, RedHatPlugin
import os
-class yum(Plugin, RedHatPlugin):
+class Yum(Plugin, RedHatPlugin):
"""yum information
"""
diff --git a/sos/utilities.py b/sos/utilities.py
index ae4763df..64d0ce62 100644
--- a/sos/utilities.py
+++ b/sos/utilities.py
@@ -35,7 +35,10 @@ import tarfile
import hashlib
import logging
import fnmatch
-import selinux
+try:
+ import selinux
+except ImportError:
+ pass
from contextlib import closing
try:
diff --git a/tests/plugin_tests.py b/tests/plugin_tests.py
index 09d4c2ac..9f8817d2 100644
--- a/tests/plugin_tests.py
+++ b/tests/plugin_tests.py
@@ -4,7 +4,8 @@ import tempfile
from StringIO import StringIO
from sos.plugins import Plugin, regex_findall, sos_relative_path, mangle_command
-from sos.utilities import Archive
+from sos.archive import TarFileArchive, ZipFileArchive
+import sos.policies
PATH = os.path.dirname(__file__)
@@ -18,7 +19,7 @@ def create_file(size):
f.close()
return f.name
-class MockArchive(Archive):
+class MockArchive(TarFileArchive):
def __init__(self):
self.m = {}
@@ -77,9 +78,7 @@ class ForbiddenMockPlugin(Plugin):
class EnablerPlugin(Plugin):
- is_installed = False
-
- def isInstalled(self, pkg):
+ def is_installed(self, pkg):
return self.is_installed
@@ -206,15 +205,15 @@ class PluginTests(unittest.TestCase):
self.assertEquals(p.get_option_as_list("opt"), ['testing'])
def test_copy_dir(self):
- self.mp.doCopyFileOrDir("tests")
+ self.mp.do_copy_file_or_dir("tests")
self.assertEquals(self.mp.archive.m["tests/plugin_tests.py"], 'tests/plugin_tests.py')
def test_copy_dir_sub(self):
- self.mp.doCopyFileOrDir("tests", sub=("tests/", "foobar/"))
+ self.mp.do_copy_file_or_dir("tests", sub=("tests/", "foobar/"))
self.assertEquals(self.mp.archive.m["tests/plugin_tests.py"], 'foobar/plugin_tests.py')
def test_copy_dir_bad_path(self):
- self.mp.doCopyFileOrDir("not_here_tests")
+ self.mp.do_copy_file_or_dir("not_here_tests")
self.assertEquals(self.mp.archive.m, {})
def test_copy_dir_forbidden_path(self):
@@ -223,7 +222,7 @@ class PluginTests(unittest.TestCase):
})
p.archive = MockArchive()
p.setup()
- p.doCopyFileOrDir("tests")
+ p.do_copy_file_or_dir("tests")
self.assertEquals(p.archive.m, {})
@@ -269,7 +268,7 @@ class AddCopySpecLimitTests(unittest.TestCase):
class CheckEnabledTests(unittest.TestCase):
def setUp(self):
- self.mp = EnablerPlugin({})
+ self.mp = EnablerPlugin({'policy': sos.policies.load()})
def test_checks_for_file(self):
f = j("tail_test.txt")
@@ -278,7 +277,6 @@ class CheckEnabledTests(unittest.TestCase):
def test_checks_for_package(self):
self.mp.packages = ('foo',)
- self.mp.is_installed = True
self.assertTrue(self.mp.check_enabled())
def test_allows_bad_tuple(self):
@@ -300,18 +298,18 @@ class RegexSubTests(unittest.TestCase):
self.mp.archive = MockArchive()
def test_file_never_copied(self):
- self.assertEquals(0, self.mp.doFileSub("never_copied", r"^(.*)$", "foobar"))
+ self.assertEquals(0, self.mp.do_file_sub("never_copied", r"^(.*)$", "foobar"))
def test_no_replacements(self):
self.mp.add_copy_spec(j("tail_test.txt"))
self.mp.collect()
- replacements = self.mp.doFileSub(j("tail_test.txt"), r"wont_match", "foobar")
+ replacements = self.mp.do_file_sub(j("tail_test.txt"), r"wont_match", "foobar")
self.assertEquals(0, replacements)
def test_replacements(self):
self.mp.add_copy_spec(j("tail_test.txt"))
self.mp.collect()
- replacements = self.mp.doFileSub(j("tail_test.txt"), r"(tail)", "foobar")
+ replacements = self.mp.do_file_sub(j("tail_test.txt"), r"(tail)", "foobar")
self.assertEquals(1, replacements)
self.assertTrue("foobar" in self.mp.archive.m.get(j('tail_test.txt')))