-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fs insert one new #166
base: client
Are you sure you want to change the base?
Fs insert one new #166
Changes from 10 commits
93d02c9
7929b81
1123853
1a01b94
6f3f475
0766efa
068a03a
142e7c4
0f305dd
4acd773
3a97060
d43a7dc
72b4dea
96b7659
ffd5961
f8569b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
**Added:** | ||
|
||
* function for inserting one document to the filesystem database | ||
|
||
**Changed:** | ||
|
||
* <news item> | ||
|
||
**Deprecated:** | ||
|
||
* <news item> | ||
|
||
**Removed:** | ||
|
||
* <news item> | ||
|
||
**Fixed:** | ||
|
||
* <news item> | ||
|
||
**Security:** | ||
|
||
* <news item> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
pydr_rc = { | ||
"groupname": "Billinge Group", | ||
"databases": [ | ||
{ | ||
"name": "local", | ||
"url": ".", | ||
"public": False, | ||
"path": "db", | ||
"local": True | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
from collections import defaultdict | ||
from pathlib import Path | ||
from testfixtures import TempDirectory | ||
|
||
import pytest | ||
import os | ||
|
||
from pydatarecognition.fsclient import FileSystemClient | ||
from pydatarecognition.runcontrol import connect_db | ||
from tests.inputs.pydr_rc import pydr_rc | ||
from tests.inputs.exemplars import EXEMPLARS | ||
|
||
# | ||
# def test_dump_json(): | ||
|
@@ -18,48 +24,40 @@ | |
# actual = f.read() | ||
# assert actual == json_doc | ||
|
||
# todo: | ||
# build a runcontrol object as in regolith. have it created globally in the | ||
# tests for reuse in all the tests (look for DEFAULT_RC in regoith tests) | ||
# for now: | ||
# DEFAULT_RC = RunControl( | ||
# _validators=DEFAULT_VALIDATORS, | ||
# builddir="_build", | ||
# mongodbpath=property(lambda self: os.path.join(self.builddir, "_dbpath")), | ||
# user_config=os.path.expanduser("~/.config/regolith/user.json"), | ||
# force=False, | ||
# database=None | ||
# ) | ||
DEFAULT_RC = {} | ||
rc = DEFAULT_RC | ||
|
||
|
||
# FileSystemClient methods tested here | ||
def test_is_alive(): | ||
def test_is_alive(rc): | ||
expected = True # filesystem is always alive! | ||
fsc = FileSystemClient(rc) | ||
actual = fsc.is_alive() | ||
|
||
assert actual == expected | ||
|
||
|
||
def test_open(): | ||
def test_open(rc): | ||
fsc = FileSystemClient(rc) | ||
fsc.open() | ||
|
||
# assert fsc.dbs == rc.databases | ||
actual = fsc.dbs | ||
expected = connect_db(rc)[1] | ||
assert actual == expected | ||
|
||
assert isinstance(fsc.dbs, type(defaultdict(lambda: defaultdict(dict)))) | ||
assert isinstance(fsc.chained_db, type(dict())) | ||
assert not fsc.closed | ||
|
||
|
||
def test_close(): | ||
def test_close(rc): | ||
fsc = FileSystemClient(rc) | ||
assert fsc.open | ||
# assert fsc.dbs == rc.databases | ||
|
||
actual = fsc.dbs | ||
expected = connect_db(rc)[1] | ||
assert actual == expected | ||
|
||
assert isinstance(fsc.dbs, type(defaultdict(lambda: defaultdict(dict)))) | ||
|
||
actual = fsc.close() | ||
fsc.close() | ||
assert fsc.dbs is None | ||
assert fsc.closed | ||
|
||
|
@@ -119,10 +117,42 @@ def test_all_documents(): | |
pass | ||
|
||
|
||
@pytest.mark.skip("Not written") | ||
def test_insert_one(): | ||
pass | ||
test_insert_cif = [({'intensity': [], 'q': [], 'ttheta': [], 'wavelength': 0.111111, '_id': 'ts1129'}, | ||
{'intensity': [], 'q': [], 'ttheta': [], 'wavelength': 0.111111, '_id': 'ts1129'})] | ||
@pytest.mark.parametrize('input, result', test_insert_cif) | ||
def test_insert_one(rc, input, result): | ||
client = FileSystemClient(rc) | ||
client.open() | ||
|
||
dbname = 'local' | ||
collname = 'calculated' | ||
|
||
client.load_database(pydr_rc['databases'][0]) | ||
|
||
client.insert_one(dbname, collname, input) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check we have the right logic here. I think it should look like:
I don't see the read so I am not sure we are testing that the file was updated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think since we are calling the |
||
|
||
assert list(client.dbs[dbname][collname].values())[-1] == result | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. per your question (which I don't see here for some reason) this may be left over from Regolith where the process is to load the entire database into memory (as client.dbs[dbname][collname]). It is then put back into the database at the end with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, quick questions here. So it's a bad practice to load client.dbs[dbname][collname] entirely using the above.> What if we implement find_one first and use it to test insert_one? For example: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we could, but I am not convinced that it is the best way. We should presumably also test that nothing else in the file was corrupted or overwritten or sthg. Also, as I mentioned before, we are not inserting cifs per se. I think insert_one should be able to insert any valid json. I think you agree, but by putting cif in the name it makes the test harder to read so I suggest changing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! Also another quick question, by inserting all the way into the database backend you mean overriding the yaml file directly instead of using client.load_db and client.dump_db? That means we have to change our insert_one function to directly access the yaml file? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, I think that is right. Regolith assumed small databases that could be stored in memory, then operations on the items could be done with do loops and list comprehensions, but with large databases we want to use the powerful database capabilities directly, so we want kind of CRUD capabilities. We may probably want the fs to be json format not yml, but otherwise, yes, I think we want to insert directly. |
||
|
||
|
||
test_insert_cif_bad = [{'bad_case_test_dict': 'bad'}, 'bad_case_test_str'] | ||
def test_insert_one_bad(rc): | ||
client = FileSystemClient(rc) | ||
client.open() | ||
|
||
dbname = 'local' | ||
collname = 'calculated' | ||
|
||
client.load_database(pydr_rc['databases'][0]) | ||
|
||
with pytest.raises(KeyError) as excinfo: | ||
client.insert_one(dbname, collname, test_insert_cif_bad[0]) | ||
assert '_id' in str(excinfo.value) | ||
print(excinfo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, how do we return info back to the user in pytest? Is print() enough? I couldn't find it on pytest docs... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't want to return anything back to the user in the tests, we just want them to pass or fail. This pattern could work
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then we need logic in the function itself so it raises an exception with the right error message. |
||
|
||
with pytest.raises(TypeError) as excinfo: | ||
client.insert_one(dbname, collname, test_insert_cif_bad[1]) | ||
assert 'dict' not in str(excinfo.value) | ||
print(excinfo) | ||
|
||
@pytest.mark.skip("Not written") | ||
def test_insert_many(): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code below seems to be testing connect_db, which should be tested in
test_connect_db
and not here. It is ok to use the function here to connect your db, but don't write tests for it here.