1. 29 Sep, 2019 1 commit
  2. 18 Sep, 2019 1 commit
  3. 15 Jul, 2019 1 commit
  4. 12 Jul, 2019 3 commits
    • */tests: Use defer instead of finally · 2b457640
      try/finally was used in a couple of places to save/restore default ZBlk
      format setting. Move the restore part close to save with the help of
      Kirill Smelkov committed
    • *: Use defer for dbclose & friends · 5c8340d2
      For tests this makes sure that if one test fails, it won't make following
      tests fail just because the next test will fail trying to lock test database.
      For regular code (demo_zbigarray.py) this is also a good thing to do -
      to always close the database irregardless of whether an exception was
      raised before program reached end of main.
      Pygolang becomes regular - not test only - dependency. Being regular
      dependency is currently required only by demo_zbigarray.py, but it will
      be also used in upcoming wcfs, so adding pygolang into wendelin.core
      dependencies aligns with the plan.
      dbclose now uses defer almost everywhere - there are still few places in
      tests, where one test function is opening/closing test database multiple
      times - those were not (yet ?) converted.
      Kirill Smelkov committed
    • */tests: Use pytest.raises in modern way · b12e319e
      Instead of
      	raises(Exception, 'code')
      	with raises(Exception):
      This removes lots of warnings, similar to below example:
      	  /home/kirr/src/wendelin/wendelin.core/bigfile/tests/test_basic.py:79: PytestDeprecationWarning: raises(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly
      	  See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec
      	    raises(ROAttributeError, "f.blksize = 1") # RO attribute
      Kirill Smelkov committed
  5. 11 Jul, 2019 3 commits
  6. 10 Jul, 2019 2 commits
  7. 09 Jul, 2019 2 commits
  8. 08 Jul, 2019 6 commits
  9. 18 Jun, 2019 4 commits
    • wendelin.core v0.13 · b26ba558
      Kirill Smelkov committed
    • tox -= Python3.5 · 76e8dc34
      Let's keep on test coverage for last 2 stable Python releases.
      Kirill Smelkov committed
    • Fix build for Python 3.7 · bca5f79e
      Starting from Python 3.7 the place to keep exception state was changed:
      NOTE ZEO4 does not wok with Python3.7, because ZEO4 uses "async" for a
      variable and that breaks because starting from Python3.7 "async" became
      a keyword.
      After the fix wendelin.core tests pass under all python2.7, python3.6
      and python3.7.
      Kirill Smelkov committed
    • tox: ZODB5.test.util needs mock · 6b5384ae
      Dependency added here:
      If we don't provide mock, e.g. py27-ZODB5-*-zeo-* breaks:
      	    def setup_module():
      	        global testdb
      	>       testdb = getTestDB()
      	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
      	.tox/py27-ZODB5-zblk1-zeo-numpy115/lib/python2.7/site-packages/wendelin/lib/testing.py:342: in getTestDB
      	    testdb = testdb_factory(testdb_uri)
      	.tox/py27-ZODB5-zblk1-zeo-numpy115/lib/python2.7/site-packages/wendelin/lib/testing.py:245: in __init__
      	    from ZEO.tests import forker
      	.tox/py27-ZODB5-zblk1-zeo-numpy115/lib/python2.7/site-packages/ZEO/tests/forker.py:29: in <module>
      	    import ZODB.tests.util
      	_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
      	    from ZODB.MappingStorage import DB
      	    import atexit
      	    import os
      	    import persistent
      	    import re
      	    import tempfile
      	    import time
      	    import transaction
      	    import unittest
      	    import warnings
      	    import ZODB.utils
      	    from ZODB.Connection import TransactionMetaData
      	    import zope.testing.setupstack
      	    from zope.testing import renormalizing
      	        from unittest import mock
      	    except ImportError:
      	>       import mock
      	E       ImportError: No module named mock
      	.tox/py27-ZODB5-zblk1-zeo-numpy115/lib/python2.7/site-packages/ZODB/tests/util.py:35: ImportError
      Kirill Smelkov committed
  10. 23 May, 2019 2 commits
    • tox: v↑ NumPy to 2 latest releases · 7fd83b61
      Kirill Smelkov committed
    • bigfile/zodb: Resync _ZBigFileH to Connection.transaction_manager on every connection reopen · d9d6adec
      This continues c7c01ce4 (bigfile/zodb: ZODB.Connection can migrate
      between threads on close/open and we have to care): Until now we were
      retrieving zconn.transaction_manager on _ZBigFileH init, and further using
      that transaction manager for every connection reopen. However that is
      not correct because on every reopen connection can be given new
      transaction manager.
      We were not practically hitting the bug because until recently ZODB was,
      by default, using the same ThreadTransactionManager manager instance as
      Connection.transaction_manager for all connections, and not doing all
      steps needed to keep _ZBigFileH.transaction_manager in sync to
      Connection was forgiven - a particular transaction manager that was used
      was TransactionManager instance implicitly associated with current
      thread by global threading.Local transaction.manager . However starting
      from ZODB 5.5.0 Connection code was changed to remember as
      .transaction_manager the particular TransactionManager instance without
      any threading.Local games:
      Given that we were not syncing properly that broke wendelin.core tests, for
          bigfile/tests/test_filezodb.py::test_bigfile_filezodb_vs_conn_migration Exception in thread Thread-1:
          Traceback (most recent call last):
            File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
            File "/usr/lib/python2.7/threading.py", line 754, in run
              self.__target(*self.__args, **self.__kwargs)
            File "/home/kirr/src/wendelin/wendelin.core/bigfile/tests/test_filezodb.py", line 401, in T11
              transaction.commit()    # should be nothing
            File "/home/kirr/src/wendelin/venv/z-dev/local/lib/python2.7/site-packages/transaction/_manager.py", line 252, in commit
              return self.manager.commit()
            File "/home/kirr/src/wendelin/venv/z-dev/local/lib/python2.7/site-packages/transaction/_manager.py", line 131, in commit
              return self.get().commit()
            File "/home/kirr/src/wendelin/venv/z-dev/local/lib/python2.7/site-packages/transaction/_transaction.py", line 298, in commit
              self._synchronizers.map(lambda s: s.beforeCompletion(self))
            File "/home/kirr/src/wendelin/venv/z-dev/local/lib/python2.7/site-packages/transaction/weakset.py", line 61, in map
            File "/home/kirr/src/wendelin/venv/z-dev/local/lib/python2.7/site-packages/transaction/_transaction.py", line 298, in <lambda>
              self._synchronizers.map(lambda s: s.beforeCompletion(self))
            File "/home/kirr/src/wendelin/wendelin.core/bigfile/file_zodb.py", line 671, in beforeCompletion
              assert txn is zconn.transaction_manager.get()
      What is happening here is that one thread used the connection and
      ZBigFile/_ZBigFileH associated with it, then the connection was closed
      and released to DB pool. Then the connection was reopened but by another
      thread and thus with different TransactionManager instance and oops -
      _ZBigFileH.transaction_manager is different because it is
      TransactionManager instance that was used by the first thread.
      Fix it by resyncing _ZBigFileH.transaction_manager on every
      connection reopen. No new test as existing tests already cover the
      problem when run with ZODB >= 5.5.0 .
      Kirill Smelkov committed
  11. 03 May, 2019 1 commit
  12. 17 Mar, 2019 1 commit
    • t/qemu-runlinux: Kernel verbosity control via -v · 208aca62
      	0: ERROR+ on boot/run
      	1: INFO+  on      run
      	2: INFO+  on boot/run
      	3: DEBUG+ on boot/run
      It is convenient not to see large kernel boot log on every test run. "1"
      (single -v) is also convenient: one can skip the boot log but still see
      details of what is going on when test workload is run. -vv and -vvv are
      there to see full picture.
      Kirill Smelkov committed
  13. 27 Feb, 2019 3 commits
  14. 13 Feb, 2019 1 commit
    • t/qemu-runlinux: Update · fe541453
      Continuing 76d8f76d (Script to run compiled linux kernel with root fs
      mounted from host) update the script to run/debug linux inside QEMU:
      - teach it to run specified program + args, instead of hardcoded /bin/sh;
      - before tailing to user program, builtin init mounts /proc, /sys, ...
        inside - previously it was /proc, /sys from host seen on those
        mountpoints and it was very misleading - e.g. ps was showing processes
        from host, not inside, etc.
      - builtin init also cares to run specified program with the same current
        directory that was current on host, and environments such as $HOME,
        $PATH, $TERM, ... are also propagated.
      - allow to optionally run QEMU with graphics, instead of stdout only;
      - increase available RAM from 128M to 512M (with 128M running py.test
        inside is failing with fork: not enough memory).
      This updated version was useful to debug WCFS(*) & FUSE issues by running
      	kirr@deco:~/src/wendelin/wendelin.core/wcfs$ ../t/qemu-runlinux ~/src/linux/linux/arch/x86_64/boot/bzImage py.test -vsx -k test_wcfs
      See https://marc.info/?l=linux-fsdevel&m=155000277921155&w=2 for details.
      (*) WCFS is still being draft and worked on t branch.
      Kirill Smelkov committed
  15. 11 Jan, 2019 1 commit
    • bigfile/py: Properly untrack PyVMA from GC before dealloc · d97641d2
      On a testing instance we started to see segfaults in pyvma_dealloc()
      with inside calls to vma_unmap but with NULL pyvma->fileh. That was
      strange, becuse before calling vma_unmap(), the code explicitly checks
      whether pyvma->fileh is !NULL.
      That was, as it turned out, due to pyvma_dealloc being called twice at the
      same time from two python threads. Here is how that was possible:
      T1 decrefs pyvma and finds its reference count drops to zero. It calls
      pyvma_dealloc. From there vma_unmap() is called, which calls virt_lock()
      and that releases GIL first. Another thread T2 was waiting for GIL, it
      acquires it, does some work at python level and somehow triggers GC.
      Since PyVMA supports cyclic GC, it was on GC list and thus GC calls
      dealloc for the same vma again. Here is how it looks in the backtraces:
      	#0  0x00007f6aefc57827 in futex_abstimed_wait_cancelable (private=0, abstime=0x0, expected=0, futex_word=0x1e011d0) at ../sysdeps/unix/sysv/linux/futex-internal.h:205
      	#1  do_futex_wait (sem=sem@entry=0x1e011d0, abstime=0x0) at sem_waitcommon.c:111
      	#2  0x00007f6aefc578d4 in __new_sem_wait_slow (sem=0x1e011d0, abstime=0x0) at sem_waitcommon.c:181
      	#3  0x00007f6aefc5797a in __new_sem_wait (sem=<optimized out>) at sem_wait.c:29
      	#4  0x00000000004ffbc4 in PyThread_acquire_lock ()
      	#5  0x00000000004dbe8a in PyEval_RestoreThread ()
      	#6  0x00007f6ac6d3b8fc in py_gil_retake_if_waslocked (arg=0x4f18f00) at bigfile/_bigfile.c:1048
      	#7  0x00007f6ac6d3dcfc in virt_gil_retake_if_waslocked (gilstate=0x4f18f00) at bigfile/virtmem.c:78
      	#8  0x00007f6ac6d3dd30 in virt_lock () at bigfile/virtmem.c:92
      	#9  0x00007f6ac6d3e724 in vma_unmap (vma=0x7f6a7e0c4100) at bigfile/virtmem.c:271
      	#10 0x00007f6ac6d3a0bc in pyvma_dealloc (pyvma0=0x7f6a7e0c40e0) at bigfile/_bigfile.c:284
      	#13 0x00000000004d76b0 in PyEval_EvalFrameEx ()
      	#5  0x00007f6ac6d3a081 in pyvma_dealloc (pyvma0=0x7f6a7e0c40e0) at bigfile/_bigfile.c:276
      	#6  0x0000000000500450 in ?? ()
      	#7  0x00000000004ffd82 in _PyObject_GC_New ()
      	#8  0x0000000000485392 in PyList_New ()
      	#9  0x00000000004d3bff in PyEval_EvalFrameEx ()
      T2 does the work of vma_unmap and clears C-level vma. Then, when T1 wakes up and
      returns to vma_unmap, it sees vma->file and all other fields cleared -> oops
      Fix it by removing pyvma from GC list before going to do actual destruction.
      This way if a concurrent GC triggers, it won't see the vma object on its list,
      and thus won't have a chance to invoke its destructor the second time.
      The bug was introduced in 450ad804 (bigarray: ArrayRef support for BigArray)
      when PyVMA was changed to be cyclic-GC aware. However at that time, even Python
      documentation itself was not saying PyObject_GC_UnTrack is needed, as it was
      added only in 2.7.15 after finding that many types in CPython itself are
      vulnerable to similar segfaults:
      It is pity, that CPython took the approach to force all type authors to
      care to invoke PyObject_GC_UnTrack explicitly, instead of doing that
      automatically in Python runtime before calling tp_dealloc.
      /cc @Tyagov, @klaus
      /reviewed-on nexedi/wendelin.core!11
      Kirill Smelkov committed
  16. 29 Oct, 2018 2 commits
    • lib.xnumpy.structured: New utility to create structured view of an array · 32ca80e2
      Structured creates view of the array interpreting its minor axis as fully covered by a dtype.
      It is similar to arr.view(dtype) + corresponding reshape, but does
      not have limitations of ndarray.view(). For example:
        In [1]: a = np.arange(3*3, dtype=np.int32).reshape((3,3))
        In [2]: a
        array([[0, 1, 2],
               [3, 4, 5],
               [6, 7, 8]], dtype=int32)
        In [3]: b = a[:2,:2]
        In [4]: b
        array([[0, 1],
               [3, 4]], dtype=int32)
        In [5]: dtxy = np.dtype([('x', np.int32), ('y', np.int32)])
        In [6]: dtxy
        Out[6]: dtype([('x', '<i4'), ('y', '<i4')])
        In [7]: b.view(dtxy)
        ValueError                                Traceback (most recent call last)
        <ipython-input-66-af98529aa150> in <module>()
        ----> 1 b.view(dtxy)
        ValueError: To change to a dtype of a different size, the array must be C-contiguous
        In [8]: structured(b, dtxy)
        Out[8]: array([(0, 1), (3, 4)], dtype=[('x', '<i4'), ('y', '<i4')])
      Structured always creates view and never copies data.
      Here is original context where separately playing with .shape and .dtype
      was not enough, since it was creating array copy and OOM'ing the machine:
      Kirill Smelkov committed
    • bigarray: Factor-out our custom numpy.lib.stride_tricks.as_strided-alike into lib/xnumpy.py · 6a5dfefa
      We are going to use this code in another place, so move this out to
      dommon place as a preparatory step first.
      On a related note: Since ArrayRef is generic and quite independent from
      BigArray (it only supports it, but equally it supports just other - e.g.
      plain arrays), the proper place for it might be also to be lib/xnumpy.py .
      We might get to this topic a bit later.
      Kirill Smelkov committed
  17. 12 Oct, 2018 2 commits
    • RAMArray · 99b91c84
      RAMArray is compatible to ZBigArray in API and semantic, but stores its
      data in RAM only. It is useful in situations where ZBigArray compatible
      data type is needed, but the amount of data is small and the data itself
      is needed only temporarily - e.g. in a simulation.
      Please see details in individual patches.
      Original merge request by @klaus (nexedi/wendelin.core!8).
      /cc @Tyagov
      /reviewed-on nexedi/wendelin.core!9
      Kirill Smelkov committed
    • bigarray: RAMArray · fc9b69d8
      RAMArray is compatible to ZBigArray in API and semantic, but stores its
      data in RAM only. It is useful in situations where ZBigArray compatible
      data type is needed, but the amount of data is small and the data itself
      is needed only temporarily - e.g. in a simulation.
      Implementation is based on mmapping temporary files from /dev/shm/... and
      passing them as file handles, similarly to how ZBigArray works, to BigArray.
      We don't use just numpy.ndarray because of append - for ZBigArray append
      works in O(1), but more importantly it does not copy data. This way
      mmapings previously created for ZBigArray views, continue to correctly
      alias array data. If we would be using ndarray directly, since
      ndarray.resize copies data, that property would not be preserved.
      Original patch by Klaus Wölfel <klaus@nexedi.com>
      Kirill Smelkov committed
  18. 11 Oct, 2018 1 commit
  19. 04 Jul, 2018 1 commit
  20. 26 Jun, 2018 2 commits