Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[test] Test the multi-delete in journaled_data
Test following situation:
         ("set", dict(path=["a"], value={"c": [1, 2, 3]})),
         ("set", dict(path=["a", "b"], value=2)),
         ("set", dict(path=["a", "c"], value=[1]))

Previously stack:

E               core.exceptions.Error:
E               ------------------------------- Patch Error ----------------------------------
E               Path:
E                  []
E               Patchset:
E                  [['a'], {'b': 0, 'c': [1, 2], 'd': {'da': ''}}]
E                  [['a', 'b'], 1]
E                  [['a', 'c', 2], 3]
E                  [['a', 'e'], {'ea': 1, 'eb': 2}]
E                  [['a', 'd']]
E                  [['a', 'b'], 2]
E                  [['a', 'd'], ['f']]
E                  [['a', 'd'], 1]
E                  [['a', 'd'], 2]
E                  [['a', 'd'], 3]
E                  [['a', 'b']]
E                  [['a', 'new'], 1]
E                  [['a', 'e', 'ec'], 'EC']
E                  [['a', 'e', 'ed'], 'ED']
E                  [['a', 'c', 1]]
E               => [['a', 'c', 2]]
E                  [['a', 'c', 1], 2]
E                  [['a', 'c', 2], 3]
E
E               Current data:
E               {
E                   "a": {
E                       "c": [
E                           1,
E                           3
E                       ],
E                       "e": {
E                           "ea": 1,
E                           "eb": 2,
E                           "ec": "EC",
E                           "ed": "ED"
E                       },
E                       "d": 3,
E                       "new": 1
E                   }
E               }
E
E               Traceback:
E                   sys.exit(pytest.main(args, plugins_to_load + [Plugin]))
E                 File ".../python3.7/site-packages/_pytest/config/__init__.py", line 165, in main
E                   config=config
E                 File ".../python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
E                   return self._hookexec(self, self.get_hookimpls(), kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
E                   return self._inner_hookexec(hook, methods, kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
E                   firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
E                 File ".../python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
E                   res = hook_impl.function(*args)
E                 File ".../python3.7/site-packages/_pytest/main.py", line 306, in pytest_cmdline_main
E                   return wrap_session(config, _main)
E                 File ".../python3.7/site-packages/_pytest/main.py", line 257, in wrap_session
E                   session.exitstatus = doit(config, session) or 0
E                 File ".../python3.7/site-packages/_pytest/main.py", line 313, in _main
E                   config.hook.pytest_runtestloop(session=session)
E                 File ".../python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
E                   return self._hookexec(self, self.get_hookimpls(), kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
E                   return self._inner_hookexec(hook, methods, kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
E                   firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
E                 File ".../python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
E                   res = hook_impl.function(*args)
E                 File ".../python3.7/site-packages/_pytest/main.py", line 338, in pytest_runtestloop
E                   item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
E                 File ".../python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
E                   return self._hookexec(self, self.get_hookimpls(), kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
E                   return self._inner_hookexec(hook, methods, kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
E                   firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
E                 File ".../python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
E                   res = hook_impl.function(*args)
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 110, in pytest_runtest_protocol
E                   runtestprotocol(item, nextitem=nextitem)
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 127, in runtestprotocol
E                   reports.append(call_and_report(item, "call", log))
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 216, in call_and_report
E                   call = call_runtest_hook(item, when, **kwds)
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 256, in call_runtest_hook
E                   lambda: ihook(item=item, **kwds), when=when, reraise=reraise
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 310, in from_call
E                   result = func()  # type: Optional[TResult]
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 256, in <lambda>
E                   lambda: ihook(item=item, **kwds), when=when, reraise=reraise
E                 File ".../python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
E                   return self._hookexec(self, self.get_hookimpls(), kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
E                   return self._inner_hookexec(hook, methods, kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
E                   firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
E                 File ".../python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
E                   res = hook_impl.function(*args)
E                 File ".../python3.7/site-packages/_pytest/runner.py", line 163, in pytest_runtest_call
E                   item.runtest()
E                 File ".../python3.7/site-packages/_pytest/python.py", line 1627, in runtest
E                   self.ihook.pytest_pyfunc_call(pyfuncitem=self)
E                 File ".../python3.7/site-packages/pluggy/hooks.py", line 286, in __call__
E                   return self._hookexec(self, self.get_hookimpls(), kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 93, in _hookexec
E                   return self._inner_hookexec(hook, methods, kwargs)
E                 File ".../python3.7/site-packages/pluggy/manager.py", line 87, in <lambda>
E                   firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
E                 File ".../python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
E                   res = hook_impl.function(*args)
E                 File ".../python3.7/site-packages/_pytest/python.py", line 184, in pytest_pyfunc_call
E                   result = testfunction(**testargs)
E                 File ".../tests/utilities/test_journaled_data.py", line 205, in test_with_full_journaling_can_apply_journal
E                   rdata.patch(patchset=data.dump_changes())
E                 File ".../utilities/journaled_data.py", line 222, in patch
E                   self._patch_lk(path=path, patchset=patchset)
E
E               Exception Traceback (most recent call last):
E                 File ".../utilities/journaled_data.py", line 235, in patch_fragment
E                   _path, _value = patch
E               ValueError: not enough values to unpack (expected 2, got 1)
E
E               During handling of the above exception, another exception occurred:
E
E               Traceback (most recent call last):
E                 File ".../utilities/journaled_data.py", line 243, in _patch
E                   patch_fragment(patch)
E                 File ".../utilities/journaled_data.py", line 239, in patch_fragment
E                   self._unset(path + _path)
E                 File ".../utilities/journaled_data.py", line 286, in _unset
E                   del data[path[-1]]
E               IndexError: list assignment index out of range
E               ------------------------------------------------------------------------------
  • Loading branch information
cgalibern committed Nov 17, 2020
1 parent d8145fe commit 0cf61f8
Showing 1 changed file with 62 additions and 14 deletions.
76 changes: 62 additions & 14 deletions opensvc/tests/utilities/test_journaled_data.py
Expand Up @@ -86,6 +86,13 @@
[{"id": 10, "data": [[["a", "e", "ec"], "EC"]]},
{"id": 11, "data": [[["a", "e", "ed"], "ED"]]},
]),

("set", dict(path=["a", "c"], value=[1]), None,
[{"id": 12, "data": [[['a', 'c', 2]], [['a', 'c', 1]]]}]),

("set", dict(path=["a", "c"], value=[1, 2, 3]), None,
[{"id": 13, "data": [[['a', 'c', 1], 2], [['a', 'c', 2], 3]]}]),

]

EXPECTED_FINAL_DATA = {"a": {"c": [1, 2, 3], "e": {"ea": 1, "eb": 2, "ec": "EC", "ed": "ED"}, "d": 3, "new": 1}}
Expand All @@ -103,7 +110,11 @@
[['a', 'b']],
[['a', 'new'], 1],
[['a', 'e', 'ec'], 'EC'],
[['a', 'e', 'ed'], 'ED']]
[['a', 'e', 'ed'], 'ED'],
[['a', 'c', 2]],
[['a', 'c', 1]],
[['a', 'c', 1], 2],
[['a', 'c', 2], 3]]

EXPECTED_CHANGES_FROM_A = [[[], {'b': 0, 'c': [1, 2], 'd': {'da': ''}}],
[['c', 2], 3],
Expand All @@ -115,10 +126,14 @@
[['d'], 3],
[['new'], 1],
[['e', 'ec'], 'EC'],
[['e', 'ed'], 'ED']]
[['e', 'ed'], 'ED'],
[['c', 2]],
[['c', 1]],
[['c', 1], 2],
[['c', 2], 3]]


def run(data):
def run(data, check_events):
for fn, kwargs, expected_result, expected_events in TEST_SCENARIO:
print("* %s(%s)" % (fn, ", ".join(["%s=%s" % (k, v) for k, v in kwargs.items()])))
if fn in ['get_copy'] and isinstance(data, JournaledDataView):
Expand All @@ -142,7 +157,8 @@ def run(data):
del(msg["ts"])
del(msg["kind"])
events.append(msg)
assert events == expected_events
if check_events:
assert events == expected_events
if hasattr(data, 'dump_changes'):
print("journal: %s" % data.dump_changes())
if hasattr(data, 'dump_data'):
Expand All @@ -151,49 +167,81 @@ def run(data):

@pytest.mark.ci
@pytest.mark.parametrize('with_queue', [True, False], ids=["with queue", "without queue"])
@pytest.mark.parametrize('check_events', [True, False], ids=["with check events", "without check events"])
class TestJournaledDataWithoutJournal(object):
@staticmethod
def test(with_queue):
def test(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(event_q=event_q, emit_interval=0)
run(data)
run(data, check_events)
assert data.dump_data() == EXPECTED_FINAL_DATA
assert data.dump_changes() == []


@pytest.mark.ci
@pytest.mark.parametrize('with_queue', [True, False], ids=["with queue", "without queue"])
@pytest.mark.parametrize('check_events', [True, False], ids=["with check events", "without check events"])
class TestJournaledDataWithJournal(object):
@staticmethod
def test_with_full_journaling(with_queue):
def test_with_full_journaling_has_expected_data(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=[], event_q=event_q, emit_interval=0)
run(data)
run(data, check_events)
assert data.dump_data() == EXPECTED_FINAL_DATA

@staticmethod
def test_with_full_journaling_has_expected_journal(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=[], event_q=event_q, emit_interval=0)
run(data, check_events)
assert data.dump_changes() == EXPECTED_CHANGES

@staticmethod
def test_with_full_journaling_can_apply_journal(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=[], event_q=event_q, emit_interval=0)
run(data, check_events)
rdata = JournaledData()
rdata.patch(patchset=data.dump_changes())
assert rdata.dump_data() == EXPECTED_FINAL_DATA

@staticmethod
def test_with_a_journaling_with_exclude_a_b(with_queue):
def test_with_a_journaling_with_exclude_a_b_has_expected_data(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=["a"], event_q=event_q, emit_interval=0, journal_exclude=[["b"]])
run(data)
run(data, check_events)
assert data.dump_data() == EXPECTED_FINAL_DATA

@staticmethod
def test_with_a_journaling_with_exclude_a_b_has_expected_journal(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=["a"], event_q=event_q, emit_interval=0, journal_exclude=[["b"]])
run(data, check_events)
assert data.dump_changes() == EXPECTED_CHANGES_FROM_A

@staticmethod
def test_with_a_journaling_with_exclude_a_b_can_apply_journal(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=["a"], event_q=event_q, emit_interval=0, journal_exclude=[["b"]])
run(data, check_events)
rdata = JournaledData()
rdata.patch(patchset=data.dump_changes())
expected_patched_copy = deepcopy(EXPECTED_FINAL_DATA["a"])
expected_patched_copy.update({"b": 0})
assert rdata.dump_data() == expected_patched_copy

@staticmethod
def test_with_a_b_journaling(with_queue):
def test_with_a_b_journaling_has_expected_data(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=["a", "b"], event_q=event_q, emit_interval=0)
run(data)
run(data, check_events)
assert data.dump_data() == EXPECTED_FINAL_DATA

@staticmethod
def test_with_a_b_journaling_expect_empty_journal(with_queue, check_events):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=["a", "b"], event_q=event_q, emit_interval=0)
run(data, check_events)
rdata = JournaledData()
rdata.patch(patchset=data.dump_changes())
assert rdata.dump_data() is None
Expand All @@ -207,7 +255,7 @@ def test_from_data_with_full_journaling(with_queue):
event_q = queue.Queue() if with_queue else None
data = JournaledData(journal_head=[], event_q=event_q, emit_interval=0)
data_view = JournaledDataView(data=data, path=[])
run(data_view)
run(data_view, False)
assert data_view.get() == EXPECTED_FINAL_DATA
assert data.dump_data() == EXPECTED_FINAL_DATA

Expand All @@ -216,6 +264,6 @@ def test_from_data_without_journaling(with_queue):
event_q = queue.Queue() if with_queue else None
data = JournaledData(event_q=event_q, emit_interval=0)
data_view = JournaledDataView(data=data, path=[])
run(data_view)
run(data_view, False)
assert data_view.get() == EXPECTED_FINAL_DATA
assert data.dump_data() == EXPECTED_FINAL_DATA

0 comments on commit 0cf61f8

Please sign in to comment.