From e12e0211af8a9cdd47d91f08891a6c081253b778 Mon Sep 17 00:00:00 2001 From: Ethan Ho Date: Thu, 14 Dec 2023 16:06:22 -0700 Subject: [PATCH 1/3] cp to tests --- tests/test_update1.py | 126 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tests/test_update1.py diff --git a/tests/test_update1.py b/tests/test_update1.py new file mode 100644 index 000000000..d2f7dc18f --- /dev/null +++ b/tests/test_update1.py @@ -0,0 +1,126 @@ +from nose.tools import assert_true, assert_false, assert_equal, raises +import os +import numpy as np +from pathlib import Path +import tempfile +import datajoint as dj +from . import PREFIX, CONN_INFO +from datajoint import DataJointError + +schema = dj.Schema(PREFIX + "_update1", connection=dj.conn(**CONN_INFO)) + +dj.config["stores"]["update_store"] = dict(protocol="file", location=tempfile.mkdtemp()) + +dj.config["stores"]["update_repo"] = dict( + stage=tempfile.mkdtemp(), protocol="file", location=tempfile.mkdtemp() +) + + +scratch_folder = tempfile.mkdtemp() + +dj.errors._switch_filepath_types(True) + + +@schema +class Thing(dj.Manual): + definition = """ + thing : int + --- + number=0 : int + frac : float + picture = null : attach@update_store + params = null : longblob + img_file = null: filepath@update_repo + timestamp = CURRENT_TIMESTAMP : datetime + """ + + +def test_update1(): + """test normal updates""" + + dj.errors._switch_filepath_types(True) + # CHECK 1 -- initial insert + key = dict(thing=1) + Thing.insert1(dict(key, frac=0.5)) + check1 = Thing.fetch1() + + # CHECK 2 -- some updates + # numbers and datetimes + Thing.update1(dict(key, number=3, frac=30, timestamp="2020-01-01 10:00:00")) + # attachment + attach_file = Path(scratch_folder, "attach1.dat") + buffer1 = os.urandom(100) + attach_file.write_bytes(buffer1) + Thing.update1(dict(key, picture=attach_file)) + attach_file.unlink() + assert_false(attach_file.is_file()) + + # filepath + stage_path = dj.config["stores"]["update_repo"]["stage"] + relpath, filename = "one/two/three", "picture.dat" + managed_file = Path(stage_path, relpath, filename) + managed_file.parent.mkdir(parents=True, exist_ok=True) + original_file_data = os.urandom(3000) + with managed_file.open("wb") as f: + f.write(original_file_data) + Thing.update1(dict(key, img_file=managed_file)) + managed_file.unlink() + assert_false(managed_file.is_file()) + + check2 = Thing.fetch1(download_path=scratch_folder) + buffer2 = Path(check2["picture"]).read_bytes() # read attachment + final_file_data = managed_file.read_bytes() # read filepath + + # CHECK 3 -- reset to default values using None + Thing.update1( + dict( + key, + number=None, + timestamp=None, + picture=None, + img_file=None, + params=np.random.randn(3, 3), + ) + ) + check3 = Thing.fetch1() + + assert_true( + check1["number"] == 0 and check1["picture"] is None and check1["params"] is None + ) + + assert_true( + check2["number"] == 3 + and check2["frac"] == 30.0 + and check2["picture"] is not None + and check2["params"] is None + and buffer1 == buffer2 + ) + + assert_true( + check3["number"] == 0 + and check3["frac"] == 30.0 + and check3["picture"] is None + and check3["img_file"] is None + and isinstance(check3["params"], np.ndarray) + ) + + assert_true(check3["timestamp"] > check2["timestamp"]) + assert_equal(buffer1, buffer2) + assert_equal(original_file_data, final_file_data) + + +@raises(DataJointError) +def test_update1_nonexistent(): + Thing.update1(dict(thing=100, frac=0.5)) # updating a non-existent entry + + +@raises(DataJointError) +def test_update1_noprimary(): + Thing.update1(dict(number=None)) # missing primary key + + +@raises(DataJointError) +def test_update1_misspelled_attribute(): + key = dict(thing=17) + Thing.insert1(dict(key, frac=1.5)) + Thing.update1(dict(key, numer=3)) # misspelled attribute From 96146418f681b4b8816347995607856094eb9837 Mon Sep 17 00:00:00 2001 From: Ethan Ho Date: Thu, 14 Dec 2023 16:06:37 -0700 Subject: [PATCH 2/3] nose2pytest test_update1 --- tests/test_update1.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/tests/test_update1.py b/tests/test_update1.py index d2f7dc18f..60dfe8c10 100644 --- a/tests/test_update1.py +++ b/tests/test_update1.py @@ -53,7 +53,7 @@ def test_update1(): attach_file.write_bytes(buffer1) Thing.update1(dict(key, picture=attach_file)) attach_file.unlink() - assert_false(attach_file.is_file()) + assert not attach_file.is_file() # filepath stage_path = dj.config["stores"]["update_repo"]["stage"] @@ -65,7 +65,7 @@ def test_update1(): f.write(original_file_data) Thing.update1(dict(key, img_file=managed_file)) managed_file.unlink() - assert_false(managed_file.is_file()) + assert not managed_file.is_file() check2 = Thing.fetch1(download_path=scratch_folder) buffer2 = Path(check2["picture"]).read_bytes() # read attachment @@ -84,29 +84,23 @@ def test_update1(): ) check3 = Thing.fetch1() - assert_true( - check1["number"] == 0 and check1["picture"] is None and check1["params"] is None - ) + assert check1["number"] == 0 and check1["picture"] is None and check1["params"] is None - assert_true( - check2["number"] == 3 + assert (check2["number"] == 3 and check2["frac"] == 30.0 and check2["picture"] is not None and check2["params"] is None - and buffer1 == buffer2 - ) + and buffer1 == buffer2) - assert_true( - check3["number"] == 0 + assert (check3["number"] == 0 and check3["frac"] == 30.0 and check3["picture"] is None and check3["img_file"] is None - and isinstance(check3["params"], np.ndarray) - ) + and isinstance(check3["params"], np.ndarray)) - assert_true(check3["timestamp"] > check2["timestamp"]) - assert_equal(buffer1, buffer2) - assert_equal(original_file_data, final_file_data) + assert check3["timestamp"] > check2["timestamp"] + assert buffer1 == buffer2 + assert original_file_data == final_file_data @raises(DataJointError) From 20ab185b7dd544c8dff4c7cc744b3879612ec4f0 Mon Sep 17 00:00:00 2001 From: Ethan Ho Date: Thu, 14 Dec 2023 16:26:15 -0700 Subject: [PATCH 3/3] Format with black --- tests/test_update1.py | 97 +++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/tests/test_update1.py b/tests/test_update1.py index 60dfe8c10..07e0e5b80 100644 --- a/tests/test_update1.py +++ b/tests/test_update1.py @@ -1,27 +1,13 @@ -from nose.tools import assert_true, assert_false, assert_equal, raises +import pytest import os import numpy as np from pathlib import Path import tempfile import datajoint as dj -from . import PREFIX, CONN_INFO +from . import PREFIX from datajoint import DataJointError -schema = dj.Schema(PREFIX + "_update1", connection=dj.conn(**CONN_INFO)) -dj.config["stores"]["update_store"] = dict(protocol="file", location=tempfile.mkdtemp()) - -dj.config["stores"]["update_repo"] = dict( - stage=tempfile.mkdtemp(), protocol="file", location=tempfile.mkdtemp() -) - - -scratch_folder = tempfile.mkdtemp() - -dj.errors._switch_filepath_types(True) - - -@schema class Thing(dj.Manual): definition = """ thing : int @@ -35,10 +21,38 @@ class Thing(dj.Manual): """ -def test_update1(): - """test normal updates""" +@pytest.fixture(scope="module") +def mock_stores_update(tmpdir_factory): + og_stores_config = dj.config.get("stores") + if "stores" not in dj.config: + dj.config["stores"] = {} + dj.config["stores"]["update_store"] = dict( + protocol="file", location=tmpdir_factory.mktemp("store") + ) + dj.config["stores"]["update_repo"] = dict( + stage=tmpdir_factory.mktemp("repo_stage"), + protocol="file", + location=tmpdir_factory.mktemp("repo_loc"), + ) + yield + if og_stores_config is None: + del dj.config["stores"] + else: + dj.config["stores"] = og_stores_config - dj.errors._switch_filepath_types(True) + +@pytest.fixture +def schema_update1(connection_test): + schema = dj.Schema( + PREFIX + "_update1", context=dict(Thing=Thing), connection=connection_test + ) + schema(Thing) + yield schema + schema.drop() + + +def test_update1(tmpdir, enable_filepath_feature, schema_update1, mock_stores_update): + """Test normal updates""" # CHECK 1 -- initial insert key = dict(thing=1) Thing.insert1(dict(key, frac=0.5)) @@ -48,7 +62,7 @@ def test_update1(): # numbers and datetimes Thing.update1(dict(key, number=3, frac=30, timestamp="2020-01-01 10:00:00")) # attachment - attach_file = Path(scratch_folder, "attach1.dat") + attach_file = Path(tmpdir, "attach1.dat") buffer1 = os.urandom(100) attach_file.write_bytes(buffer1) Thing.update1(dict(key, picture=attach_file)) @@ -67,7 +81,7 @@ def test_update1(): managed_file.unlink() assert not managed_file.is_file() - check2 = Thing.fetch1(download_path=scratch_folder) + check2 = Thing.fetch1(download_path=tmpdir) buffer2 = Path(check2["picture"]).read_bytes() # read attachment final_file_data = managed_file.read_bytes() # read filepath @@ -84,37 +98,50 @@ def test_update1(): ) check3 = Thing.fetch1() - assert check1["number"] == 0 and check1["picture"] is None and check1["params"] is None + assert ( + check1["number"] == 0 and check1["picture"] is None and check1["params"] is None + ) - assert (check2["number"] == 3 + assert ( + check2["number"] == 3 and check2["frac"] == 30.0 and check2["picture"] is not None and check2["params"] is None - and buffer1 == buffer2) + and buffer1 == buffer2 + ) - assert (check3["number"] == 0 + assert ( + check3["number"] == 0 and check3["frac"] == 30.0 and check3["picture"] is None and check3["img_file"] is None - and isinstance(check3["params"], np.ndarray)) + and isinstance(check3["params"], np.ndarray) + ) assert check3["timestamp"] > check2["timestamp"] assert buffer1 == buffer2 assert original_file_data == final_file_data -@raises(DataJointError) -def test_update1_nonexistent(): - Thing.update1(dict(thing=100, frac=0.5)) # updating a non-existent entry +def test_update1_nonexistent( + enable_filepath_feature, schema_update1, mock_stores_update +): + with pytest.raises(DataJointError): + # updating a non-existent entry + Thing.update1(dict(thing=100, frac=0.5)) -@raises(DataJointError) -def test_update1_noprimary(): - Thing.update1(dict(number=None)) # missing primary key +def test_update1_noprimary(enable_filepath_feature, schema_update1, mock_stores_update): + with pytest.raises(DataJointError): + # missing primary key + Thing.update1(dict(number=None)) -@raises(DataJointError) -def test_update1_misspelled_attribute(): +def test_update1_misspelled_attribute( + enable_filepath_feature, schema_update1, mock_stores_update +): key = dict(thing=17) Thing.insert1(dict(key, frac=1.5)) - Thing.update1(dict(key, numer=3)) # misspelled attribute + with pytest.raises(DataJointError): + # misspelled attribute + Thing.update1(dict(key, numer=3))