Skip to content

Commit cd70d7f

Browse files
committed
Enable to call any extended HTTP methods, adding shortcut for options, head and propfind DAV method.
1 parent bebd45f commit cd70d7f

4 files changed

Lines changed: 73 additions & 33 deletions

File tree

CHANGES.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@ New Features
3030
<https://github.com/nuxeo/FunkLoad/tree/master/contrib/FunkloadNagios>`_
3131
examples.
3232

33+
* Extends HTTP methods with HEAD and OPTIONS, enable to send any
34+
methods using the new ``method`` api, adding PROPFIND DAV exemple ::
35+
36+
# requests for options
37+
self.options(server_url, description="options")
38+
self.propfind(server_url + '/dav/foo', depth=1, description="propfind")
39+
# put a lock using the new method api
40+
data = Data('text/xml', """<?xml version="1.0" encoding="utf-8"?>
41+
<D:lockinfo xmlns:D="DAV:">
42+
<D:lockscope><D:exclusive/></D:lockscope>
43+
<D:locktype><D:write/></D:locktype>
44+
<D:owner>
45+
<D:href>http://www.apple.com/webdav_fs/</D:href>
46+
</D:owner>
47+
</D:lockinfo>""")
48+
self.method("LOCK", server_url + "/somedocpath", params=data, description="lock")
49+
50+
3351
* GH-9: New options for distributed mode: you can specify the Python binary
3452
to use with ``--distribute-python=PYTHON_BIN`` option and additional
3553
packages to install on slaves with the

TODO.txt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,47 @@ missing, See the [[http://funkload.nuxeo.org/reporting.html][reporting section]]
88
Current target release is 1.15.0
99

1010
* Features
11-
** TODO Matplotlib integration :@next:REPORT:
12-
** TODO Add a param to join to next request action :@next:CORE:
11+
** TODO Matplotlib integration :@next:REPORT:
12+
** TODO Add a param to join to next request action :@next:CORE:
1313
Joining distinct requests into a single page/action:
1414

1515
self.get(url, description="foo", join_with_next_req=True)
1616
self.get(url2)
1717

1818
url2 is reported as being on the same page as url, there is no
1919
thinktime pause between the 2 requests.
20-
** TODO Finish funkload.metadata impl :@next:
20+
** TODO Finish funkload.metadata impl :@next:
2121
fl-buil-report should render the funkload.metadata file if present
2222
** TODO Produce gplot script with commented extended options :@next:REPORT:
2323
- explain how to have small label on trend reports
2424
export GDFONTPATH=/usr/share/fonts/truetype/freefont
2525
set label "Some comment" at 2,51,1 rotate by 45 front font 'FreeSans,6'
2626
- ex of eps output
27-
** TODO Add unit test on request :@next:QA:
27+
** TODO Add unit test on request :@next:QA:
2828
using simple file req/resp as tcpwatch + minimal fake web server.
29-
** TODO Provide new sysstat monitoring plugin :@next:CORE:
30-
** TODO Provide csv monitoring plugin :@next:CORE:
29+
** TODO Provide new sysstat monitoring plugin :@next:CORE:
30+
** TODO Provide csv monitoring plugin :@next:CORE:
3131
make the same charts than in [[http://public.dev.nuxeo.com/~ben/logchart/monitor.html][logchart]]
32-
** TODO Add common utils :@next:CORE:
32+
** TODO Add common utils :@next:CORE:
3333
- extractToken(buffer, start, stop, maxlen=-1)
3434
- getRandomLineInFile()
3535
- assertAndDump() dump getBody on failure
36-
** TODO Improve report failure section :@next:REPORT:
36+
** TODO Improve report failure section :@next:REPORT:
3737
Add an error section with:
3838
- http failure:
3939
- sort by page|req|code
4040
- display a link to the returned page if any
4141
- Assertion error:
4242
- sort by traceback
43-
** TODO Look at what can be done with perfbase :@next:TBD:
43+
** TODO Look at what can be done with perfbase :@next:TBD:
4444
http://perfbase.tigris.org/
4545
* Bugs
46-
** TODO Patch cookie lib :@next:CORE:
46+
** TODO Patch cookie lib :@next:CORE:
4747
The cookie lib is too restrictive, try to merge the refactoring
4848
done by Google:
4949
http://svn.nuxeo.org/trac/pub/browser/funkload/branches/google-refactoring
5050
Added: [2010-11-18 jeu. 14:23
51-
** TODO Produce valid xml test result :@next:REPORT:
51+
** TODO Produce valid xml test result :@next:REPORT:
5252
the root element is missing
5353
* org-mode configuration
5454

src/funkload/FunkLoadTestCase.py

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def __init__(self, methodName='runTest', options=None):
7070
self.suite_name = self.__class__.__name__
7171
unittest.TestCase.__init__(self, methodName=self.test_name)
7272
self._response = None
73-
self.options = options
73+
self._options = options
7474
self.debug_level = getattr(options, 'debug_level', 0)
7575
self._funkload_init()
7676
self._dump_dir = getattr(options, 'dump_dir', None)
@@ -226,11 +226,11 @@ def _connect(self, url, params, ok_codes, rtype, description, redirect=False):
226226
self.total_time += t_delta
227227
if redirect:
228228
self.total_redirects += 1
229-
elif rtype in ('post', 'get', 'put', 'delete'):
229+
elif rtype != 'link':
230230
self.total_pages += 1
231-
elif rtype == 'link':
231+
else:
232232
self.total_links += 1
233-
233+
234234
if rtype in ('put','post', 'get', 'delete'):
235235
# this is a valid referer for the next request
236236
self.setHeader('Referer', url)
@@ -289,10 +289,6 @@ def _browse(self, url_in, params_in=None,
289289
if not self.in_bench_mode:
290290
self.logd('GET: %s\n\tPage %i: %s ...' % (url, self.steps,
291291
description or ''))
292-
elif method == 'delete':
293-
if not self.in_bench_mode:
294-
self.logd('DELETE:%s\n\tPage %i: %s ...' %(url, self.steps,
295-
description or ''))
296292
else:
297293
url = url_in
298294
if not self.in_bench_mode:
@@ -372,7 +368,7 @@ def _browse(self, url_in, params_in=None,
372368
text = ('End of loop: %d pages rendered in %.3fs, '
373369
'avg of %.3fs per page, '
374370
'%.3f SPPS without concurrency.' % (count, t_delta,
375-
t_delta/count,
371+
t_delta / count,
376372
count/t_delta))
377373
self.logi(text)
378374
trace(text + '\n')
@@ -394,23 +390,48 @@ def get(self, url, params=None, description=None, ok_codes=None):
394390
response = self._browse(url, params, description, ok_codes,
395391
method="get")
396392
return response
397-
398-
def put(self, url, params=None, description=None, ok_codes=None):
399-
"""PUT method on url with params."""
393+
394+
def method(self, method, url, params=None, description=None,
395+
ok_codes=None):
396+
"""Generic method request can be used to submit MOVE, MKCOL or
397+
whatever method name request."""
400398
self.steps += 1
401399
self.page_responses = 0
402400
response = self._browse(url, params, description, ok_codes,
403-
method="put")
401+
method=method)
404402
return response
405-
403+
404+
def put(self, url, params=None, description=None, ok_codes=None):
405+
"""PUT method."""
406+
return self.method('put', url, params, description, ok_codes)
407+
406408
def delete(self, url, description=None, ok_codes=None):
407409
"""DELETE method on url."""
408-
self.steps += 1
409-
self.page_responses = 0
410-
response = self._browse(url, None, description, ok_codes,
411-
method="delete")
412-
return response
413-
410+
return self.method('delete', url, None, description, ok_codes)
411+
412+
def head(self, url, description=None, ok_codes=None):
413+
"""HEAD method on url adding params."""
414+
return self.method('head', url, None, description, ok_codes)
415+
416+
def options(self, url, description=None, ok_codes=None):
417+
"""OPTIONS method on url."""
418+
return self.method('options', url, None, description, ok_codes)
419+
420+
def propfind(self, url, params=None, depth=None, description=None,
421+
ok_codes=None):
422+
"""DAV PROPFIND method."""
423+
if ok_codes is None:
424+
codes = [207, ]
425+
else:
426+
codes = ok_codes
427+
if depth is not None:
428+
self.setHeader('depth', str(depth))
429+
ret = self.method('PROPFIND', url, params=params,
430+
description=description, ok_codes=codes)
431+
if depth is not None:
432+
self.delHeader('depth')
433+
return ret
434+
414435
def exists(self, url, params=None, description="Checking existence"):
415436
"""Try a GET on URL return True if the page exists or False."""
416437
resp = self.get(url, params, description=description,
@@ -634,7 +655,7 @@ def conf_get(self, section, key, default=_marker, quiet=False):
634655
"""Return an entry from the options or configuration file."""
635656
# check for a command line options
636657
opt_key = '%s_%s' % (section, key)
637-
opt_val = getattr(self.options, opt_key, None)
658+
opt_val = getattr(self._options, opt_key, None)
638659
if opt_val:
639660
#print('[%s] %s = %s from options.' % (section, key, opt_val))
640661
return opt_val

src/funkload/PatchWebunit.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ def WF_fetch(self, url, postdata=None, server=None, port=None, protocol=None,
278278
if isinstance(postdata, Data):
279279
# User data and content_type
280280
params = postdata.data
281-
headers.append(('Content-type', postdata.content_type))
281+
if postdata.content_type:
282+
headers.append(('Content-type', postdata.content_type))
282283
else:
283284
# Check for File upload
284285
is_multipart = False

0 commit comments

Comments
 (0)