Import python-mockupdb_1.2.1.orig.tar.gz
Ondřej Nový
6 years ago
0 | *~ | |
1 | *#* | |
2 | .DS* | |
3 | *.class | |
4 | *.pyc | |
5 | *.pyd | |
6 | build/ | |
7 | dist/ | |
8 | .tox | |
9 | *.egg | |
10 | *.egg-info | |
11 | .eggs | |
12 | docs/_build |
1 | 1 | |
2 | 2 | Changelog |
3 | 3 | ========= |
4 | ||
5 | 1.2.1 (2017-12-06) | |
6 | ------------------ | |
7 | ||
8 | Set minWireVersion to 0, not to 2. I had been wrong about MongoDB 3.6's wire | |
9 | version range: it's actually 0 to 6. MockupDB now reports the same wire version | |
10 | range as MongoDB 3.6 by default. | |
11 | ||
12 | 1.2.0 (2017-09-22) | |
13 | ------------------ | |
14 | ||
15 | Update for MongoDB 3.6: report minWireVersion 2 and maxWireVersion 6 by default. | |
16 | ||
17 | 1.1.3 (2017-04-23) | |
18 | ------------------ | |
19 | ||
20 | Avoid rare RuntimeError in close(), if a client thread shuts down a socket as | |
21 | MockupDB iterates its list of sockets. | |
22 | ||
23 | 1.1.2 (2016-08-23) | |
24 | ------------------ | |
25 | ||
26 | Properly detect closed sockets so ``MockupDB.stop()`` doesn't take 10 seconds | |
27 | per connection. Thanks to Sean Purcell. | |
28 | ||
29 | 1.1.1 (2016-08-01) | |
30 | ------------------ | |
31 | ||
32 | Don't use "client" as a keyword arg for ``Request``, it conflicts with the | |
33 | actual "client" field in drivers' new handshake protocol. | |
4 | 34 | |
5 | 35 | 1.1.0 (2016-02-11) |
6 | 36 | ------------------ |
0 | .PHONY: clean-pyc clean-build docs clean | |
1 | ||
2 | help: | |
3 | @echo "clean - remove all build, test, coverage and Python artifacts" | |
4 | @echo "clean-build - remove build artifacts" | |
5 | @echo "clean-pyc - remove Python file artifacts" | |
6 | @echo "clean-test - remove test and coverage artifacts" | |
7 | @echo "lint - check style with flake8" | |
8 | @echo "test - run tests quickly with the default Python" | |
9 | @echo "test-all - run tests on every Python version with tox" | |
10 | @echo "coverage - check code coverage quickly with the default Python" | |
11 | @echo "docs - generate Sphinx HTML documentation, including API docs" | |
12 | @echo "release - package and upload a release" | |
13 | @echo "dist - package" | |
14 | @echo "install - install the package to the active Python's site-packages" | |
15 | ||
16 | clean: clean-build clean-pyc clean-test | |
17 | ||
18 | clean-build: | |
19 | rm -fr build/ | |
20 | rm -fr dist/ | |
21 | rm -fr .eggs/ | |
22 | find . -name '*.egg-info' -exec rm -fr {} + | |
23 | find . -name '*.egg' -exec rm -f {} + | |
24 | ||
25 | clean-pyc: | |
26 | find . -name '*.pyc' -exec rm -f {} + | |
27 | find . -name '*.pyo' -exec rm -f {} + | |
28 | find . -name '*~' -exec rm -f {} + | |
29 | find . -name '__pycache__' -exec rm -fr {} + | |
30 | ||
31 | clean-test: | |
32 | rm -fr .tox/ | |
33 | rm -f .coverage | |
34 | rm -fr htmlcov/ | |
35 | ||
36 | lint: | |
37 | flake8 mockupdb tests | |
38 | ||
39 | test: | |
40 | python setup.py test | |
41 | ||
42 | test-all: | |
43 | tox | |
44 | ||
45 | coverage: | |
46 | coverage run --source mockupdb setup.py test | |
47 | coverage report -m | |
48 | coverage html | |
49 | open htmlcov/index.html | |
50 | ||
51 | docs: | |
52 | rm -f docs/mockupdb.rst | |
53 | rm -f docs/modules.rst | |
54 | sphinx-apidoc -o docs/ mockupdb | |
55 | $(MAKE) -C docs clean | |
56 | $(MAKE) -C docs html | |
57 | open docs/_build/html/index.html | |
58 | ||
59 | release: clean | |
60 | python setup.py sdist upload | |
61 | python setup.py bdist_wheel upload | |
62 | ||
63 | dist: clean | |
64 | python setup.py sdist | |
65 | python setup.py bdist_wheel | |
66 | ls -l dist | |
67 | ||
68 | install: clean | |
69 | python setup.py install |
0 | Metadata-Version: 1.1 | |
1 | Name: mockupdb | |
2 | Version: 1.2.1 | |
3 | Summary: MongoDB Wire Protocol server library | |
4 | Home-page: https://github.com/ajdavis/mongo-mockup-db | |
5 | Author: A. Jesse Jiryu Davis | |
6 | Author-email: jesse@mongodb.com | |
7 | License: Apache License, Version 2.0 | |
8 | Description-Content-Type: UNKNOWN | |
9 | Description: ======== | |
10 | MockupDB | |
11 | ======== | |
12 | ||
13 | Mock server for testing MongoDB clients and creating MongoDB Wire Protocol | |
14 | servers. | |
15 | ||
16 | * Documentation: http://mockupdb.readthedocs.org/ | |
17 | ||
18 | ||
19 | ||
20 | ||
21 | Changelog | |
22 | ========= | |
23 | ||
24 | 1.2.1 (2017-12-06) | |
25 | ------------------ | |
26 | ||
27 | Set minWireVersion to 0, not to 2. I had been wrong about MongoDB 3.6's wire | |
28 | version range: it's actually 0 to 6. MockupDB now reports the same wire version | |
29 | range as MongoDB 3.6 by default. | |
30 | ||
31 | 1.2.0 (2017-09-22) | |
32 | ------------------ | |
33 | ||
34 | Update for MongoDB 3.6: report minWireVersion 2 and maxWireVersion 6 by default. | |
35 | ||
36 | 1.1.3 (2017-04-23) | |
37 | ------------------ | |
38 | ||
39 | Avoid rare RuntimeError in close(), if a client thread shuts down a socket as | |
40 | MockupDB iterates its list of sockets. | |
41 | ||
42 | 1.1.2 (2016-08-23) | |
43 | ------------------ | |
44 | ||
45 | Properly detect closed sockets so ``MockupDB.stop()`` doesn't take 10 seconds | |
46 | per connection. Thanks to Sean Purcell. | |
47 | ||
48 | 1.1.1 (2016-08-01) | |
49 | ------------------ | |
50 | ||
51 | Don't use "client" as a keyword arg for ``Request``, it conflicts with the | |
52 | actual "client" field in drivers' new handshake protocol. | |
53 | ||
54 | 1.1.0 (2016-02-11) | |
55 | ------------------ | |
56 | ||
57 | Add cursor_id property to OpGetMore, and ssl parameter to interactive_server. | |
58 | ||
59 | 1.0.3 (2015-09-12) | |
60 | ------------------ | |
61 | ||
62 | ``MockupDB(auto_ismaster=True)`` had just responded ``{"ok": 1}``, but this | |
63 | isn't enough to convince PyMongo 3 it's talking to a valid standalone, | |
64 | so auto-respond ``{"ok": 1, "ismaster": True}``. | |
65 | ||
66 | 1.0.2 (2015-09-11) | |
67 | ------------------ | |
68 | ||
69 | Restore Request.assert_matches method, used in pymongo-mockup-tests. | |
70 | ||
71 | 1.0.1 (2015-09-11) | |
72 | ------------------ | |
73 | ||
74 | Allow co-installation with PyMongo. | |
75 | ||
76 | 1.0.0 (2015-09-10) | |
77 | ------------------ | |
78 | ||
79 | First release. | |
80 | ||
81 | 0.1.0 (2015-02-25) | |
82 | ------------------ | |
83 | ||
84 | Development begun. | |
85 | ||
86 | Keywords: mongo,mongodb,wire protocol,mockupdb,mock | |
87 | Platform: UNKNOWN | |
88 | Classifier: Development Status :: 2 - Pre-Alpha | |
89 | Classifier: Intended Audience :: Developers | |
90 | Classifier: License :: OSI Approved :: Apache Software License | |
91 | Classifier: Natural Language :: English | |
92 | Classifier: Programming Language :: Python :: 2 | |
93 | Classifier: Programming Language :: Python :: 2.6 | |
94 | Classifier: Programming Language :: Python :: 2.7 | |
95 | Classifier: Programming Language :: Python :: 3 | |
96 | Classifier: Programming Language :: Python :: 3.3 | |
97 | Classifier: Programming Language :: Python :: 3.4 |
0 | /* | |
1 | * sidebar.js | |
2 | * ~~~~~~~~~~ | |
3 | * | |
4 | * This script makes the Sphinx sidebar collapsible and implements intelligent | |
5 | * scrolling. | |
6 | * | |
7 | * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds in | |
8 | * .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton used to | |
9 | * collapse and expand the sidebar. | |
10 | * | |
11 | * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden and the | |
12 | * width of the sidebar and the margin-left of the document are decreased. | |
13 | * When the sidebar is expanded the opposite happens. This script saves a | |
14 | * per-browser/per-session cookie used to remember the position of the sidebar | |
15 | * among the pages. Once the browser is closed the cookie is deleted and the | |
16 | * position reset to the default (expanded). | |
17 | * | |
18 | * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. | |
19 | * :license: BSD, see LICENSE for details. | |
20 | * | |
21 | */ | |
22 | ||
23 | $(function() { | |
24 | // global elements used by the functions. | |
25 | // the 'sidebarbutton' element is defined as global after its | |
26 | // creation, in the add_sidebar_button function | |
27 | var jwindow = $(window); | |
28 | var jdocument = $(document); | |
29 | var bodywrapper = $('.bodywrapper'); | |
30 | var sidebar = $('.sphinxsidebar'); | |
31 | var sidebarwrapper = $('.sphinxsidebarwrapper'); | |
32 | ||
33 | // original margin-left of the bodywrapper and width of the sidebar | |
34 | // with the sidebar expanded | |
35 | var bw_margin_expanded = bodywrapper.css('margin-left'); | |
36 | var ssb_width_expanded = sidebar.width(); | |
37 | ||
38 | // margin-left of the bodywrapper and width of the sidebar | |
39 | // with the sidebar collapsed | |
40 | var bw_margin_collapsed = '.8em'; | |
41 | var ssb_width_collapsed = '.8em'; | |
42 | ||
43 | // colors used by the current theme | |
44 | var dark_color = '#AAAAAA'; | |
45 | var light_color = '#CCCCCC'; | |
46 | ||
47 | function get_viewport_height() { | |
48 | if (window.innerHeight) | |
49 | return window.innerHeight; | |
50 | else | |
51 | return jwindow.height(); | |
52 | } | |
53 | ||
54 | function sidebar_is_collapsed() { | |
55 | return sidebarwrapper.is(':not(:visible)'); | |
56 | } | |
57 | ||
58 | function toggle_sidebar() { | |
59 | if (sidebar_is_collapsed()) | |
60 | expand_sidebar(); | |
61 | else | |
62 | collapse_sidebar(); | |
63 | // adjust the scrolling of the sidebar | |
64 | scroll_sidebar(); | |
65 | } | |
66 | ||
67 | function collapse_sidebar() { | |
68 | sidebarwrapper.hide(); | |
69 | sidebar.css('width', ssb_width_collapsed); | |
70 | bodywrapper.css('margin-left', bw_margin_collapsed); | |
71 | sidebarbutton.css({ | |
72 | 'margin-left': '0', | |
73 | 'height': bodywrapper.height(), | |
74 | 'border-radius': '5px' | |
75 | }); | |
76 | sidebarbutton.find('span').text('»'); | |
77 | sidebarbutton.attr('title', _('Expand sidebar')); | |
78 | document.cookie = 'sidebar=collapsed'; | |
79 | } | |
80 | ||
81 | function expand_sidebar() { | |
82 | bodywrapper.css('margin-left', bw_margin_expanded); | |
83 | sidebar.css('width', ssb_width_expanded); | |
84 | sidebarwrapper.show(); | |
85 | sidebarbutton.css({ | |
86 | 'margin-left': ssb_width_expanded-12, | |
87 | 'height': bodywrapper.height(), | |
88 | 'border-radius': '0 5px 5px 0' | |
89 | }); | |
90 | sidebarbutton.find('span').text('«'); | |
91 | sidebarbutton.attr('title', _('Collapse sidebar')); | |
92 | //sidebarwrapper.css({'padding-top': | |
93 | // Math.max(window.pageYOffset - sidebarwrapper.offset().top, 10)}); | |
94 | document.cookie = 'sidebar=expanded'; | |
95 | } | |
96 | ||
97 | function add_sidebar_button() { | |
98 | sidebarwrapper.css({ | |
99 | 'float': 'left', | |
100 | 'margin-right': '0', | |
101 | 'width': ssb_width_expanded - 28 | |
102 | }); | |
103 | // create the button | |
104 | sidebar.append( | |
105 | '<div id="sidebarbutton"><span>«</span></div>' | |
106 | ); | |
107 | var sidebarbutton = $('#sidebarbutton'); | |
108 | // find the height of the viewport to center the '<<' in the page | |
109 | var viewport_height = get_viewport_height(); | |
110 | var sidebar_offset = sidebar.offset().top; | |
111 | var sidebar_height = Math.max(bodywrapper.height(), sidebar.height()); | |
112 | sidebarbutton.find('span').css({ | |
113 | 'display': 'block', | |
114 | 'position': 'fixed', | |
115 | 'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10 | |
116 | }); | |
117 | ||
118 | sidebarbutton.click(toggle_sidebar); | |
119 | sidebarbutton.attr('title', _('Collapse sidebar')); | |
120 | sidebarbutton.css({ | |
121 | 'border-radius': '0 5px 5px 0', | |
122 | 'color': '#444444', | |
123 | 'background-color': '#CCCCCC', | |
124 | 'font-size': '1.2em', | |
125 | 'cursor': 'pointer', | |
126 | 'height': sidebar_height, | |
127 | 'padding-top': '1px', | |
128 | 'padding-left': '1px', | |
129 | 'margin-left': ssb_width_expanded - 12 | |
130 | }); | |
131 | ||
132 | sidebarbutton.hover( | |
133 | function () { | |
134 | $(this).css('background-color', dark_color); | |
135 | }, | |
136 | function () { | |
137 | $(this).css('background-color', light_color); | |
138 | } | |
139 | ); | |
140 | } | |
141 | ||
142 | function set_position_from_cookie() { | |
143 | if (!document.cookie) | |
144 | return; | |
145 | var items = document.cookie.split(';'); | |
146 | for(var k=0; k<items.length; k++) { | |
147 | var key_val = items[k].split('='); | |
148 | var key = key_val[0]; | |
149 | if (key == 'sidebar') { | |
150 | var value = key_val[1]; | |
151 | if ((value == 'collapsed') && (!sidebar_is_collapsed())) | |
152 | collapse_sidebar(); | |
153 | else if ((value == 'expanded') && (sidebar_is_collapsed())) | |
154 | expand_sidebar(); | |
155 | } | |
156 | } | |
157 | } | |
158 | ||
159 | add_sidebar_button(); | |
160 | var sidebarbutton = $('#sidebarbutton'); | |
161 | set_position_from_cookie(); | |
162 | ||
163 | ||
164 | /* intelligent scrolling */ | |
165 | function scroll_sidebar() { | |
166 | var sidebar_height = sidebarwrapper.height(); | |
167 | var viewport_height = get_viewport_height(); | |
168 | var offset = sidebar.position()['top']; | |
169 | var wintop = jwindow.scrollTop(); | |
170 | var winbot = wintop + viewport_height; | |
171 | var curtop = sidebarwrapper.position()['top']; | |
172 | var curbot = curtop + sidebar_height; | |
173 | // does sidebar fit in window? | |
174 | if (sidebar_height < viewport_height) { | |
175 | // yes: easy case -- always keep at the top | |
176 | sidebarwrapper.css('top', $u.min([$u.max([0, wintop - offset - 10]), | |
177 | jdocument.height() - sidebar_height - 200])); | |
178 | } | |
179 | else { | |
180 | // no: only scroll if top/bottom edge of sidebar is at | |
181 | // top/bottom edge of window | |
182 | if (curtop > wintop && curbot > winbot) { | |
183 | sidebarwrapper.css('top', $u.max([wintop - offset - 10, 0])); | |
184 | } | |
185 | else if (curtop < wintop && curbot < winbot) { | |
186 | sidebarwrapper.css('top', $u.min([winbot - sidebar_height - offset - 20, | |
187 | jdocument.height() - sidebar_height - 200])); | |
188 | } | |
189 | } | |
190 | } | |
191 | jwindow.scroll(scroll_sidebar); | |
192 | }); |
1 | 1 | Installation |
2 | 2 | ============ |
3 | 3 | |
4 | MockMongoDB requires PyMongo_. It uses PyMongo's ``bson`` package to encode | |
5 | and decode MongoDB Wire Protocol message bodies. | |
4 | Install MockupDB with pip: | |
6 | 5 | |
7 | At the command line:: | |
8 | ||
9 | $ easy_install mongo-mockup-db | |
10 | ||
11 | Or, if you have virtualenvwrapper installed:: | |
12 | ||
13 | $ mkvirtualenv mongo-mockup-db | |
14 | $ pip install mongo-mockup-db | |
15 | ||
16 | .. _PyMongo: https://pypi.python.org/pypi/pymongo/ | |
6 | $ python -m pip install mongo-mockup-db |
0 | @import url("default.css"); | |
1 | ||
2 | body { | |
3 | background-color: white; | |
4 | margin-left: 1em; | |
5 | margin-right: 1em; | |
6 | } | |
7 | ||
8 | div.related { | |
9 | margin-bottom: 1.2em; | |
10 | padding: 0.5em 0; | |
11 | border-top: 1px solid #ccc; | |
12 | margin-top: 0.5em; | |
13 | } | |
14 | ||
15 | div.related a:hover { | |
16 | color: #0095C4; | |
17 | } | |
18 | ||
19 | div.related:first-child { | |
20 | border-top: 0; | |
21 | border-bottom: 1px solid #ccc; | |
22 | } | |
23 | ||
24 | div.sphinxsidebar { | |
25 | background-color: #eeeeee; | |
26 | border-radius: 5px; | |
27 | line-height: 130%; | |
28 | font-size: smaller; | |
29 | } | |
30 | ||
31 | div.sphinxsidebar h3, div.sphinxsidebar h4 { | |
32 | margin-top: 1.5em; | |
33 | } | |
34 | ||
35 | div.sphinxsidebarwrapper > h3:first-child { | |
36 | margin-top: 0.2em; | |
37 | } | |
38 | ||
39 | div.sphinxsidebarwrapper > ul > li > ul > li { | |
40 | margin-bottom: 0.4em; | |
41 | } | |
42 | ||
43 | div.sphinxsidebar a:hover { | |
44 | color: #0095C4; | |
45 | } | |
46 | ||
47 | div.sphinxsidebar input { | |
48 | font-family: 'Lucida Grande',Arial,sans-serif; | |
49 | border: 1px solid #999999; | |
50 | font-size: smaller; | |
51 | border-radius: 3px; | |
52 | } | |
53 | ||
54 | div.sphinxsidebar input[type=text] { | |
55 | max-width: 150px; | |
56 | } | |
57 | ||
58 | div.body { | |
59 | padding: 0 0 0 1.2em; | |
60 | } | |
61 | ||
62 | div.body p { | |
63 | line-height: 140%; | |
64 | } | |
65 | ||
66 | div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { | |
67 | margin: 0; | |
68 | border: 0; | |
69 | padding: 0.3em 0; | |
70 | } | |
71 | ||
72 | div.body hr { | |
73 | border: 0; | |
74 | background-color: #ccc; | |
75 | height: 1px; | |
76 | } | |
77 | ||
78 | div.body pre { | |
79 | border-radius: 3px; | |
80 | border: 1px solid #ac9; | |
81 | } | |
82 | ||
83 | div.body div.admonition, div.body div.impl-detail { | |
84 | border-radius: 3px; | |
85 | } | |
86 | ||
87 | div.body div.impl-detail > p { | |
88 | margin: 0; | |
89 | } | |
90 | ||
91 | div.body div.seealso { | |
92 | border: 1px solid #dddd66; | |
93 | } | |
94 | ||
95 | div.body a { | |
96 | color: #0072aa; | |
97 | } | |
98 | ||
99 | div.body a:visited { | |
100 | color: #6363bb; | |
101 | } | |
102 | ||
103 | div.body a:hover { | |
104 | color: #00B0E4; | |
105 | } | |
106 | ||
107 | tt, code, pre { | |
108 | font-family: monospace, sans-serif; | |
109 | font-size: 96.5%; | |
110 | } | |
111 | ||
112 | div.body tt, div.body code { | |
113 | border-radius: 3px; | |
114 | } | |
115 | ||
116 | div.body tt.descname, div.body code.descname { | |
117 | font-size: 120%; | |
118 | } | |
119 | ||
120 | div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { | |
121 | font-weight: normal; | |
122 | } | |
123 | ||
124 | .deprecated { | |
125 | border-radius: 3px; | |
126 | } | |
127 | ||
128 | table.docutils { | |
129 | border: 1px solid #ddd; | |
130 | min-width: 20%; | |
131 | border-radius: 3px; | |
132 | margin-top: 10px; | |
133 | margin-bottom: 10px; | |
134 | } | |
135 | ||
136 | table.docutils td, table.docutils th { | |
137 | border: 1px solid #ddd !important; | |
138 | border-radius: 3px; | |
139 | } | |
140 | ||
141 | table p, table li { | |
142 | text-align: left !important; | |
143 | } | |
144 | ||
145 | table.docutils th { | |
146 | background-color: #eee; | |
147 | padding: 0.3em 0.5em; | |
148 | } | |
149 | ||
150 | table.docutils td { | |
151 | background-color: white; | |
152 | padding: 0.3em 0.5em; | |
153 | } | |
154 | ||
155 | table.footnote, table.footnote td { | |
156 | border: 0 !important; | |
157 | } | |
158 | ||
159 | div.footer { | |
160 | line-height: 150%; | |
161 | margin-top: -2em; | |
162 | text-align: right; | |
163 | width: auto; | |
164 | margin-right: 10px; | |
165 | } | |
166 | ||
167 | div.footer a:hover { | |
168 | color: #0095C4; | |
169 | } | |
170 | ||
171 | .refcount { | |
172 | color: #060; | |
173 | } | |
174 | ||
175 | .stableabi { | |
176 | color: #229; | |
177 | } |
0 | [theme] | |
1 | inherit = default | |
2 | stylesheet = pydoctheme.css | |
3 | pygments_style = sphinx | |
4 | ||
5 | [options] | |
6 | bodyfont = 'Lucida Grande', Arial, sans-serif | |
7 | headfont = 'Lucida Grande', Arial, sans-serif | |
8 | footerbgcolor = white | |
9 | footertextcolor = #555555 | |
10 | relbarbgcolor = white | |
11 | relbartextcolor = #666666 | |
12 | relbarlinkcolor = #444444 | |
13 | sidebarbgcolor = white | |
14 | sidebartextcolor = #444444 | |
15 | sidebarlinkcolor = #444444 | |
16 | bgcolor = white | |
17 | textcolor = #222222 | |
18 | linkcolor = #0090c0 | |
19 | visitedlinkcolor = #00608f | |
20 | headtextcolor = #1a1a1a | |
21 | headbgcolor = white | |
22 | headlinkcolor = #aaaaaa |
35 | 35 | |
36 | 36 | __author__ = 'A. Jesse Jiryu Davis' |
37 | 37 | __email__ = 'jesse@mongodb.com' |
38 | __version__ = '1.1' | |
38 | __version__ = '1.2.1' | |
39 | 39 | |
40 | 40 | import collections |
41 | 41 | import contextlib |
342 | 342 | def __init__(self, *args, **kwargs): |
343 | 343 | self._flags = kwargs.pop('flags', None) |
344 | 344 | self._namespace = kwargs.pop('namespace', None) |
345 | self._client = kwargs.pop('client', None) | |
345 | self._client = kwargs.pop('_client', None) | |
346 | 346 | self._request_id = kwargs.pop('request_id', None) |
347 | self._server = kwargs.pop('server', None) | |
347 | self._server = kwargs.pop('_server', None) | |
348 | 348 | self._verbose = self._server and self._server.verbose |
349 | 349 | self._server_port = kwargs.pop('server_port', None) |
350 | 350 | self._docs = make_docs(*args, **kwargs) |
552 | 552 | assert len(docs) == 1 |
553 | 553 | command_ns = namespace[:-len('.$cmd')] |
554 | 554 | return Command(docs, namespace=command_ns, flags=flags, |
555 | client=client, request_id=request_id, server=server) | |
555 | _client=client, request_id=request_id, | |
556 | _server=server) | |
556 | 557 | else: |
557 | 558 | if len(docs) == 1: |
558 | 559 | fields = None |
561 | 562 | fields = docs[1] |
562 | 563 | return OpQuery(docs[0], fields=fields, namespace=namespace, |
563 | 564 | flags=flags, num_to_skip=num_to_skip, |
564 | num_to_return=num_to_return, client=client, | |
565 | request_id=request_id, server=server) | |
565 | num_to_return=num_to_return, _client=client, | |
566 | request_id=request_id, _server=server) | |
566 | 567 | |
567 | 568 | def __init__(self, *args, **kwargs): |
568 | 569 | fields = kwargs.pop('fields', None) |
676 | 677 | num_to_return, = _UNPACK_INT(msg[pos:pos + 4]) |
677 | 678 | pos += 4 |
678 | 679 | cursor_id, = _UNPACK_LONG(msg[pos:pos + 8]) |
679 | return OpGetMore(namespace=namespace, flags=flags, client=client, | |
680 | return OpGetMore(namespace=namespace, flags=flags, _client=client, | |
680 | 681 | num_to_return=num_to_return, cursor_id=cursor_id, |
681 | request_id=request_id, server=server) | |
682 | request_id=request_id, _server=server) | |
682 | 683 | |
683 | 684 | def __init__(self, **kwargs): |
684 | 685 | self._num_to_return = kwargs.pop('num_to_return', None) |
712 | 713 | for _ in range(num_of_cursor_ids): |
713 | 714 | cursor_ids.append(_UNPACK_INT(msg[pos:pos+4])[0]) |
714 | 715 | pos += 4 |
715 | return OpKillCursors(client=client, cursor_ids=cursor_ids, | |
716 | server=server) | |
716 | return OpKillCursors(_client=client, cursor_ids=cursor_ids, | |
717 | _server=server) | |
717 | 718 | |
718 | 719 | def __init__(self, **kwargs): |
719 | 720 | self._cursor_ids = kwargs.pop('cursor_ids', None) |
747 | 748 | flags, = _UNPACK_INT(msg[:4]) |
748 | 749 | namespace, pos = _get_c_string(msg, 4) |
749 | 750 | docs = _bson.decode_all(msg[pos:], CODEC_OPTIONS) |
750 | return cls(*docs, namespace=namespace, flags=flags, client=client, | |
751 | request_id=request_id, server=server) | |
751 | return cls(*docs, namespace=namespace, flags=flags, _client=client, | |
752 | request_id=request_id, _server=server) | |
752 | 753 | |
753 | 754 | |
754 | 755 | class OpUpdate(_LegacyWrite): |
766 | 767 | # First 4 bytes of OP_UPDATE are "reserved". |
767 | 768 | namespace, pos = _get_c_string(msg, 4) |
768 | 769 | flags, = _UNPACK_INT(msg[pos:pos + 4]) |
769 | docs = _bson.decode_all(msg[pos+4:], CODEC_OPTIONS) | |
770 | return cls(*docs, namespace=namespace, flags=flags, client=client, | |
771 | request_id=request_id, server=server) | |
770 | docs = _bson.decode_all(msg[pos + 4:], CODEC_OPTIONS) | |
771 | return cls(*docs, namespace=namespace, flags=flags, _client=client, | |
772 | request_id=request_id, _server=server) | |
772 | 773 | |
773 | 774 | |
774 | 775 | class OpDelete(_LegacyWrite): |
786 | 787 | # First 4 bytes of OP_DELETE are "reserved". |
787 | 788 | namespace, pos = _get_c_string(msg, 4) |
788 | 789 | flags, = _UNPACK_INT(msg[pos:pos + 4]) |
789 | docs = _bson.decode_all(msg[pos+4:], CODEC_OPTIONS) | |
790 | return cls(*docs, namespace=namespace, flags=flags, client=client, | |
791 | request_id=request_id, server=server) | |
790 | docs = _bson.decode_all(msg[pos + 4:], CODEC_OPTIONS) | |
791 | return cls(*docs, namespace=namespace, flags=flags, _client=client, | |
792 | request_id=request_id, _server=server) | |
792 | 793 | |
793 | 794 | |
794 | 795 | class OpReply(object): |
1096 | 1097 | - `auto_ismaster`: pass ``True`` to autorespond ``{'ok': 1}`` to |
1097 | 1098 | ismaster requests, or pass a dict or `OpReply`. |
1098 | 1099 | - `ssl`: pass ``True`` to require SSL. |
1100 | - `min_wire_version`: the minWireVersion to include in ismaster responses | |
1101 | if `auto_ismaster` is True, default 0. | |
1102 | - `max_wire_version`: the maxWireVersion to include in ismaster responses | |
1103 | if `auto_ismaster` is True, default 6. | |
1099 | 1104 | """ |
1100 | 1105 | def __init__(self, port=None, verbose=False, |
1101 | 1106 | request_timeout=10, auto_ismaster=None, |
1102 | ssl=False): | |
1107 | ssl=False, min_wire_version=0, max_wire_version=6): | |
1103 | 1108 | self._address = ('localhost', port) |
1104 | 1109 | self._verbose = verbose |
1105 | 1110 | self._label = None |
1124 | 1129 | self._autoresponders = [] |
1125 | 1130 | |
1126 | 1131 | if auto_ismaster is True: |
1127 | self.autoresponds(Command('ismaster'), {'ismaster': True}) | |
1132 | self.autoresponds(Command('ismaster'), | |
1133 | {'ismaster': True, | |
1134 | 'minWireVersion': min_wire_version, | |
1135 | 'maxWireVersion': max_wire_version}) | |
1128 | 1136 | elif auto_ismaster: |
1129 | 1137 | self.autoresponds(Command('ismaster'), auto_ismaster) |
1130 | 1138 | |
1150 | 1158 | threads = [self._accept_thread] |
1151 | 1159 | threads.extend(self._server_threads) |
1152 | 1160 | self._listening_sock.close() |
1153 | for sock in self._server_socks: | |
1161 | for sock in list(self._server_socks): | |
1154 | 1162 | sock.close() |
1155 | 1163 | |
1156 | 1164 | with self._unlock(): |
1575 | 1583 | """Receive `length` bytes from a socket object.""" |
1576 | 1584 | msg = b'' |
1577 | 1585 | while length: |
1578 | if select.select([sock.fileno()], [], [], 1): | |
1586 | if select.select([sock.fileno()], [], [], 1)[0]: | |
1579 | 1587 | try: |
1580 | 1588 | chunk = sock.recv(length) |
1581 | 1589 | if chunk == b'': |
0 | Metadata-Version: 1.1 | |
1 | Name: mockupdb | |
2 | Version: 1.2.1 | |
3 | Summary: MongoDB Wire Protocol server library | |
4 | Home-page: https://github.com/ajdavis/mongo-mockup-db | |
5 | Author: A. Jesse Jiryu Davis | |
6 | Author-email: jesse@mongodb.com | |
7 | License: Apache License, Version 2.0 | |
8 | Description-Content-Type: UNKNOWN | |
9 | Description: ======== | |
10 | MockupDB | |
11 | ======== | |
12 | ||
13 | Mock server for testing MongoDB clients and creating MongoDB Wire Protocol | |
14 | servers. | |
15 | ||
16 | * Documentation: http://mockupdb.readthedocs.org/ | |
17 | ||
18 | ||
19 | ||
20 | ||
21 | Changelog | |
22 | ========= | |
23 | ||
24 | 1.2.1 (2017-12-06) | |
25 | ------------------ | |
26 | ||
27 | Set minWireVersion to 0, not to 2. I had been wrong about MongoDB 3.6's wire | |
28 | version range: it's actually 0 to 6. MockupDB now reports the same wire version | |
29 | range as MongoDB 3.6 by default. | |
30 | ||
31 | 1.2.0 (2017-09-22) | |
32 | ------------------ | |
33 | ||
34 | Update for MongoDB 3.6: report minWireVersion 2 and maxWireVersion 6 by default. | |
35 | ||
36 | 1.1.3 (2017-04-23) | |
37 | ------------------ | |
38 | ||
39 | Avoid rare RuntimeError in close(), if a client thread shuts down a socket as | |
40 | MockupDB iterates its list of sockets. | |
41 | ||
42 | 1.1.2 (2016-08-23) | |
43 | ------------------ | |
44 | ||
45 | Properly detect closed sockets so ``MockupDB.stop()`` doesn't take 10 seconds | |
46 | per connection. Thanks to Sean Purcell. | |
47 | ||
48 | 1.1.1 (2016-08-01) | |
49 | ------------------ | |
50 | ||
51 | Don't use "client" as a keyword arg for ``Request``, it conflicts with the | |
52 | actual "client" field in drivers' new handshake protocol. | |
53 | ||
54 | 1.1.0 (2016-02-11) | |
55 | ------------------ | |
56 | ||
57 | Add cursor_id property to OpGetMore, and ssl parameter to interactive_server. | |
58 | ||
59 | 1.0.3 (2015-09-12) | |
60 | ------------------ | |
61 | ||
62 | ``MockupDB(auto_ismaster=True)`` had just responded ``{"ok": 1}``, but this | |
63 | isn't enough to convince PyMongo 3 it's talking to a valid standalone, | |
64 | so auto-respond ``{"ok": 1, "ismaster": True}``. | |
65 | ||
66 | 1.0.2 (2015-09-11) | |
67 | ------------------ | |
68 | ||
69 | Restore Request.assert_matches method, used in pymongo-mockup-tests. | |
70 | ||
71 | 1.0.1 (2015-09-11) | |
72 | ------------------ | |
73 | ||
74 | Allow co-installation with PyMongo. | |
75 | ||
76 | 1.0.0 (2015-09-10) | |
77 | ------------------ | |
78 | ||
79 | First release. | |
80 | ||
81 | 0.1.0 (2015-02-25) | |
82 | ------------------ | |
83 | ||
84 | Development begun. | |
85 | ||
86 | Keywords: mongo,mongodb,wire protocol,mockupdb,mock | |
87 | Platform: UNKNOWN | |
88 | Classifier: Development Status :: 2 - Pre-Alpha | |
89 | Classifier: Intended Audience :: Developers | |
90 | Classifier: License :: OSI Approved :: Apache Software License | |
91 | Classifier: Natural Language :: English | |
92 | Classifier: Programming Language :: Python :: 2 | |
93 | Classifier: Programming Language :: Python :: 2.6 | |
94 | Classifier: Programming Language :: Python :: 2.7 | |
95 | Classifier: Programming Language :: Python :: 3 | |
96 | Classifier: Programming Language :: Python :: 3.3 | |
97 | Classifier: Programming Language :: Python :: 3.4 |
0 | AUTHORS.rst | |
1 | CHANGELOG.rst | |
2 | CONTRIBUTING.rst | |
3 | LICENSE | |
4 | MANIFEST.in | |
5 | README.rst | |
6 | setup.cfg | |
7 | setup.py | |
8 | docs/Makefile | |
9 | docs/authors.rst | |
10 | docs/changelog.rst | |
11 | docs/conf.py | |
12 | docs/contributing.rst | |
13 | docs/index.rst | |
14 | docs/installation.rst | |
15 | docs/make.bat | |
16 | docs/readme.rst | |
17 | docs/reference.rst | |
18 | docs/tutorial.rst | |
19 | mockupdb/__init__.py | |
20 | mockupdb/__main__.py | |
21 | mockupdb/server.pem | |
22 | mockupdb.egg-info/PKG-INFO | |
23 | mockupdb.egg-info/SOURCES.txt | |
24 | mockupdb.egg-info/dependency_links.txt | |
25 | mockupdb.egg-info/not-zip-safe | |
26 | mockupdb.egg-info/top_level.txt | |
27 | mockupdb/_bson/__init__.py | |
28 | mockupdb/_bson/binary.py | |
29 | mockupdb/_bson/code.py | |
30 | mockupdb/_bson/codec_options.py | |
31 | mockupdb/_bson/dbref.py | |
32 | mockupdb/_bson/errors.py | |
33 | mockupdb/_bson/int64.py | |
34 | mockupdb/_bson/json_util.py | |
35 | mockupdb/_bson/max_key.py | |
36 | mockupdb/_bson/min_key.py | |
37 | mockupdb/_bson/objectid.py | |
38 | mockupdb/_bson/py3compat.py | |
39 | mockupdb/_bson/regex.py | |
40 | mockupdb/_bson/son.py | |
41 | mockupdb/_bson/timestamp.py | |
42 | mockupdb/_bson/tz_util.py | |
43 | tests/__init__.py | |
44 | tests/test_mockupdb.py⏎ |
0 | mockupdb |
23 | 23 | |
24 | 24 | setup( |
25 | 25 | name='mockupdb', |
26 | version='1.1', | |
26 | version='1.2.1', | |
27 | 27 | description="MongoDB Wire Protocol server library", |
28 | 28 | long_description=readme + '\n\n' + changelog, |
29 | 29 | author="A. Jesse Jiryu Davis", |
140 | 140 | self.server.run() |
141 | 141 | self.addCleanup(self.server.stop) |
142 | 142 | self.client = MongoClient(self.server.uri) |
143 | self.collection = self.client.db.collection | |
143 | self.collection = self.client.db.get_collection( | |
144 | 'collection', write_concern=WriteConcern(w=0)) | |
144 | 145 | |
145 | 146 | def test_insert_one(self): |
146 | with going(self.collection.insert_one, {'_id': 1}) as future: | |
147 | with going(self.collection.insert_one, {'_id': 1}): | |
147 | 148 | self.server.receives(OpInsert({'_id': 1}, flags=0)) |
148 | self.server.receives(Command('getlasterror')).replies_to_gle() | |
149 | ||
150 | self.assertEqual(1, future().inserted_id) | |
151 | 149 | |
152 | 150 | def test_insert_many(self): |
153 | 151 | collection = self.collection.with_options( |
155 | 153 | |
156 | 154 | flags = INSERT_FLAGS['ContinueOnError'] |
157 | 155 | docs = [{'_id': 1}, {'_id': 2}] |
158 | with going(collection.insert_many, docs, ordered=False) as future: | |
156 | with going(collection.insert_many, docs, ordered=False): | |
159 | 157 | self.server.receives(OpInsert(docs, flags=flags)) |
160 | 158 | |
161 | self.assertEqual([1, 2], future().inserted_ids) | |
162 | ||
163 | 159 | def test_replace_one(self): |
164 | with going(self.collection.replace_one, {}, {}) as future: | |
160 | with going(self.collection.replace_one, {}, {}): | |
165 | 161 | self.server.receives(OpUpdate({}, {}, flags=0)) |
166 | request = self.server.receives(Command('getlasterror')) | |
167 | request.replies_to_gle(upserted=1) | |
168 | ||
169 | self.assertEqual(1, future().upserted_id) | |
170 | 162 | |
171 | 163 | def test_update_many(self): |
172 | 164 | flags = UPDATE_FLAGS['MultiUpdate'] |
173 | with going(self.collection.update_many, {}, {'$unset': 'a'}) as future: | |
165 | with going(self.collection.update_many, {}, {'$unset': 'a'}): | |
174 | 166 | update = self.server.receives(OpUpdate({}, {}, flags=flags)) |
175 | 167 | self.assertEqual(2, update.flags) |
176 | gle = self.server.receives(Command('getlasterror')) | |
177 | gle.replies_to_gle(upserted=1) | |
178 | ||
179 | self.assertEqual(1, future().upserted_id) | |
180 | 168 | |
181 | 169 | def test_delete_one(self): |
182 | 170 | flags = DELETE_FLAGS['SingleRemove'] |
183 | with going(self.collection.delete_one, {}) as future: | |
171 | with going(self.collection.delete_one, {}): | |
184 | 172 | delete = self.server.receives(OpDelete({}, flags=flags)) |
185 | 173 | self.assertEqual(1, delete.flags) |
186 | gle = self.server.receives(Command('getlasterror')) | |
187 | gle.replies_to_gle(n=1) | |
188 | ||
189 | self.assertEqual(1, future().deleted_count) | |
190 | 174 | |
191 | 175 | def test_delete_many(self): |
192 | with going(self.collection.delete_many, {}) as future: | |
176 | with going(self.collection.delete_many, {}): | |
193 | 177 | delete = self.server.receives(OpDelete({}, flags=0)) |
194 | 178 | self.assertEqual(0, delete.flags) |
195 | gle = self.server.receives(Command('getlasterror')) | |
196 | gle.replies_to_gle(n=2) | |
197 | ||
198 | self.assertEqual(2, future().deleted_count) | |
199 | 179 | |
200 | 180 | |
201 | 181 | class TestMatcher(unittest.TestCase): |
274 | 254 | if j == 3: |
275 | 255 | break |
276 | 256 | |
257 | def test_default_wire_version(self): | |
258 | server = MockupDB(auto_ismaster=True) | |
259 | server.run() | |
260 | self.addCleanup(server.stop) | |
261 | ismaster = MongoClient(server.uri).admin.command('isMaster') | |
262 | self.assertEqual(ismaster['minWireVersion'], 0) | |
263 | self.assertEqual(ismaster['maxWireVersion'], 6) | |
264 | ||
265 | def test_wire_version(self): | |
266 | server = MockupDB(auto_ismaster=True, | |
267 | min_wire_version=1, | |
268 | max_wire_version=42) | |
269 | server.run() | |
270 | self.addCleanup(server.stop) | |
271 | ismaster = MongoClient(server.uri).admin.command('isMaster') | |
272 | self.assertEqual(ismaster['minWireVersion'], 1) | |
273 | self.assertEqual(ismaster['maxWireVersion'], 42) | |
274 | ||
277 | 275 | |
278 | 276 | class TestResponse(unittest.TestCase): |
279 | 277 | def test_ok(self): |
0 | [tox] | |
1 | envlist = | |
2 | {py26,py27,py33,py34}-test, | |
3 | {py26,py27,py33,py34}-doctest | |
4 | ||
5 | [testenv] | |
6 | setenv = | |
7 | PYTHONPATH = {toxinidir}:{toxinidir}/mockupdb | |
8 | changedir = | |
9 | doctest: docs | |
10 | commands = | |
11 | test: python setup.py test | |
12 | doctest: sphinx-build -q -E -n -b doctest . {envtmpdir}/doctest | |
13 | ||
14 | deps = | |
15 | doctest: sphinx | |
16 | doctest: pymongo>=3 | |
17 | py26-doctest: ordereddict |