I've been messing with a patch to the depot server which is helping
me to suss out various transport issues. I've dubbed it "nasty mode".
To use:
./depot.py --nasty=<nasty-level> -d /aux0/test/repo -p 22222
The nasty-level is a number between 1 and 100 (0 would be "off")
which sets the likelihood of the server doing something nasty
like:
- Timing out
- Sending a bad response
- Sending no response
- Sending a partial response
- Todo: Sending a corrupted response
- Todo: Sending the wrong manifest
- Todo: Sending some random HTML instead of e.g. the catalog
Running the client against a server configured this way yields
a variety of tracebacks which hopefully we can clean up.
Attached is the patch. I'm leaving for vacation soon-- hopefully
someone can take this over and get it pushed. I think it will make
resiliency testing a lot more tractable.
For a reasonable test, I would start with nasty=5.
I'm not sure this patch is 100% right, FYI-- when I try to return
a '504' to the client, it's seeing it as 500. So perhaps some
cherrypy hackery is needed.
Another possibility would be to clean this up to allow the user
to toggle on and off different pathologies...
--nasty=504,timeout,multipletimeout --nasty-level=5
Thoughts?
-dp
--
Daniel Price - Solaris Kernel Engineering - [EMAIL PROTECTED] - blogs.sun.com/dp
diff -r 48f7e9d2b1ac src/depot.py
--- a/src/depot.py Tue Oct 07 15:41:50 2008 -0500
+++ b/src/depot.py Tue Oct 07 17:43:46 2008 -0700
@@ -65,6 +65,8 @@
REINDEX_DEFAULT = False
# Not in mirror mode by default
MIRROR_DEFAULT = False
+# Not in nasty mode by default
+NASTY_DEFAULT = 0
import getopt
import logging
@@ -109,15 +111,18 @@
emsg(text)
print """\
-Usage: /usr/lib/pkg.depotd [--readonly] [--rebuild] [--mirror] [--proxy-base
url]
- [--log-access dest] [--log-errors dest] [-d repo_dir] [-p port]
- [-s threads] [-t socket_timeout]
+Usage: /usr/lib/pkg.depotd [--readonly] [--rebuild] [--mirror] [--nasty]
+ [--proxy-base url] [--log-access dest] [--log-errors dest]
+ [-d repo_dir] [-p port] [-s threads] [-t socket_timeout]
--readonly Read-only operation; modifying operations disallowed
--rebuild Re-build the catalog from pkgs in depot
Cannot be used with --readonly or --mirror
--mirror Content mirror mode. Publishing and metadata operations
disabled
+ --nasty=level "Be a bad server" mode. Time out, fail, restart, etc.
+ at random. Level of nastiness (1 to 100) can be
+ configured
--proxy-base The url to use as the base for generating internal
redirects and content.
--log-access The destination for any access related information
@@ -148,6 +153,7 @@
reindex = REINDEX_DEFAULT
proxy_base = None
mirror = MIRROR_DEFAULT
+ nasty = NASTY_DEFAULT
if "PKG_REPO" in os.environ:
repo_path = os.environ["PKG_REPO"]
@@ -170,7 +176,7 @@
opt = None
try:
long_opts = ["readonly", "rebuild", "mirror", "refresh-index",
- "proxy-base="]
+ "proxy-base=", "nasty="]
for opt in log_opts:
long_opts.append("%s=" % opt.lstrip('--'))
opts, pargs = getopt.getopt(sys.argv[1:], "d:np:s:t:",
@@ -230,6 +236,9 @@
elif opt == "--mirror":
mirror = True
+ elif opt == "--nasty":
+ nasty = int(arg)
+
except getopt.GetoptError, e:
usage("pkg.depotd: %s" % e.msg)
except OptionError, e:
@@ -270,6 +279,9 @@
if mirror:
scfg.set_mirror()
+
+ if nasty:
+ scfg.set_nasty(nasty)
try:
scfg.init_dirs()
diff -r 48f7e9d2b1ac src/modules/server/config.py
--- a/src/modules/server/config.py Tue Oct 07 15:41:50 2008 -0500
+++ b/src/modules/server/config.py Tue Oct 07 17:43:46 2008 -0700
@@ -30,6 +30,7 @@
import os.path
import statvfs
import shutil
+import random
import pkg.server.catalog as catalog
import pkg.updatelog as updatelog
@@ -64,6 +65,7 @@
self.flist_requests = 0
self.flist_files = 0
self.pkgs_renamed = 0
+ self.nasty = 0
def init_dirs(self):
@@ -109,6 +111,25 @@
def set_mirror(self):
self.mirror = True
+
+ def set_nasty(self, level):
+ self.nasty = level
+
+
+ def need_nasty(self):
+ if random.randint(1,100) <= self.nasty:
+ return True
+ return False
+
+ def need_nasty_rarely(self):
+ if random.randint(1,500) <= self.nasty:
+ return True
+ return False
+
+ def need_nasty_very_rarely(self):
+ if random.randint(1,2000) <= self.nasty:
+ return True
+ return False
def is_read_only(self):
return self.read_only
@@ -183,6 +204,9 @@
self.file_requests, self.flist_requests, self.flist_files,
self.pkgs_renamed)
+ if self.nasty:
+ ret += """<br/><b><font color="red">""" + \
+ """Warning: nasty mode enabled</font></b>"""
return ret
def inc_catalog(self):
diff -r 48f7e9d2b1ac src/modules/server/repository.py
--- a/src/modules/server/repository.py Tue Oct 07 15:41:50 2008 -0500
+++ b/src/modules/server/repository.py Tue Oct 07 17:43:46 2008 -0700
@@ -264,6 +264,15 @@
# have been sent. But because we've sent data already (never
# mind the response header), we can't raise an exception here,
# or an INTERNAL_SERVER_ERROR header will get sent as well.
+
+ # NASTY
+ if self.scfg.need_nasty():
+ return
+
+ # NASTY
+ if self.scfg.need_nasty():
+ raise cherrypy.HTTPError(httplib.GATEWAY_TIMEOUT)
+
try:
return self.scfg.updatelog.send(cherrypy.request,
cherrypy.response)
@@ -283,6 +292,16 @@
interpretation of the catalog and its image policies. """
self.scfg.inc_manifest()
+
+ # NASTY
+ # emit an http error code the client should
+ # know how to retry
+ if self.scfg.need_nasty():
+ raise cherrypy.HTTPError(httplib.GATEWAY_TIMEOUT)
+
+ if self.scfg.need_nasty_rarely():
+ import time
+ time.sleep(10)
# Parse request into FMRI component and decode.
try:
@@ -328,12 +347,27 @@
try:
self.scfg.inc_flist()
+ # NASTY
+ if self.scfg.need_nasty_rarely():
+ return
+
+ # NASTY
+ # emit an http error code the client should
+ # know how to retry
+ if self.scfg.need_nasty():
+ raise
cherrypy.HTTPError(httplib.GATEWAY_TIMEOUT)
+
# Create a dummy file object that hooks to the write()
# callable which is all tarfile needs to output the
# stream. This will write the bytes to the client
# through our parent server process.
f = Dummy()
f.write = cherrypy.response.write
+
+ # NASTY
+ if self.scfg.need_nasty():
+ f.write("NASTY")
+ return
tar_stream = tarfile.open(mode = "w|",
fileobj = f)
@@ -351,7 +385,24 @@
cherrypy.request.hooks.attach('on_end_request',
self._tar_stream_close, failsafe = True)
+ if self.scfg.need_nasty():
+ import time
+ time.sleep(10)
+
for v in params.values():
+ # NASTY
+ if self.scfg.need_nasty_rarely():
+ break
+
+ # NASTY
+ if self.scfg.need_nasty_rarely():
+ continue
+
+ # NASTY
+ if self.scfg.need_nasty_very_rarely():
+ import time
+ time.sleep(10)
+
filepath = os.path.normpath(os.path.join(
self.scfg.file_root,
misc.hash_file_name(v)))
_______________________________________________
pkg-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/pkg-discuss