run unittest on multiple platforms
This commit is contained in:
parent
596ed08395
commit
a042377a7b
7 changed files with 280 additions and 84 deletions
143
.github/workflows/main.yml
vendored
143
.github/workflows/main.yml
vendored
|
@ -10,62 +10,11 @@ jobs:
|
|||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- run: make install tools
|
||||
- run: pip install -e .[lint]
|
||||
- run: make lint
|
||||
|
||||
tests-unit:
|
||||
name: "tests / unit"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- run: make install tools
|
||||
- working-directory: lbry
|
||||
env:
|
||||
HOME: /tmp
|
||||
run: coverage run -p --source=lbry -m unittest discover -vv tests.unit
|
||||
|
||||
tests-integration:
|
||||
name: "tests / integration"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
test:
|
||||
- datanetwork
|
||||
- blockchain
|
||||
- other
|
||||
db:
|
||||
- postgres
|
||||
- sqlite
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:12
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- if: matrix.test == 'other'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends ffmpeg
|
||||
- run: pip install tox-travis
|
||||
- env:
|
||||
TEST_DB: ${{ matrix.db }}
|
||||
run: tox -e ${{ matrix.test }}
|
||||
|
||||
build:
|
||||
needs: ["lint", "tests-unit", "tests-integration"]
|
||||
name: "build"
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
|
@ -78,19 +27,77 @@ jobs:
|
|||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Setup
|
||||
run: |
|
||||
pip install pyinstaller
|
||||
pip install -e .
|
||||
- if: startsWith(matrix.os, 'windows') == false
|
||||
name: Build & Run (Unix)
|
||||
run: |
|
||||
pyinstaller --onefile --name lbrynet lbry/extras/cli.py
|
||||
chmod +x dist/lbrynet
|
||||
dist/lbrynet --version
|
||||
- if: startsWith(matrix.os, 'windows')
|
||||
name: Build & Run (Windows)
|
||||
run: |
|
||||
pip install pywin32
|
||||
pyinstaller --additional-hooks-dir=scripts/. --icon=icons/lbry256.ico --onefile --name lbrynet lbry/extras/cli.py
|
||||
dist/lbrynet.exe --version
|
||||
- run: pip install -e .[test]
|
||||
- working-directory: lbry
|
||||
env:
|
||||
HOME: /tmp
|
||||
run: coverage run -p --source=lbry -m unittest -vv tests.unit.test_conf
|
||||
#run: coverage run -p --source=lbry -m unittest discover -vv tests.unit
|
||||
|
||||
# tests-integration:
|
||||
# name: "tests / integration"
|
||||
# runs-on: ubuntu-latest
|
||||
# strategy:
|
||||
# matrix:
|
||||
# test:
|
||||
# - datanetwork
|
||||
# - blockchain
|
||||
# - other
|
||||
# db:
|
||||
# - postgres
|
||||
# - sqlite
|
||||
# services:
|
||||
# postgres:
|
||||
# image: postgres:12
|
||||
# env:
|
||||
# POSTGRES_USER: postgres
|
||||
# POSTGRES_PASSWORD: postgres
|
||||
# POSTGRES_DB: postgres
|
||||
# ports:
|
||||
# - 5432:5432
|
||||
# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
# steps:
|
||||
# - uses: actions/checkout@v1
|
||||
# - uses: actions/setup-python@v1
|
||||
# with:
|
||||
# python-version: '3.7'
|
||||
# - if: matrix.test == 'other'
|
||||
# run: |
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install -y --no-install-recommends ffmpeg
|
||||
# - run: pip install tox-travis
|
||||
# - env:
|
||||
# TEST_DB: ${{ matrix.db }}
|
||||
# run: tox -e ${{ matrix.test }}
|
||||
#
|
||||
# build:
|
||||
# needs: ["lint", "tests-unit", "tests-integration"]
|
||||
# name: "build"
|
||||
# strategy:
|
||||
# matrix:
|
||||
# os:
|
||||
# - ubuntu-latest
|
||||
# - macos-latest
|
||||
# - windows-latest
|
||||
# runs-on: ${{ matrix.os }}
|
||||
# steps:
|
||||
# - uses: actions/checkout@v1
|
||||
# - uses: actions/setup-python@v1
|
||||
# with:
|
||||
# python-version: '3.7'
|
||||
# - name: Setup
|
||||
# run: |
|
||||
# pip install pyinstaller
|
||||
# pip install -e .
|
||||
# - if: startsWith(matrix.os, 'windows') == false
|
||||
# name: Build & Run (Unix)
|
||||
# run: |
|
||||
# pyinstaller --onefile --name lbrynet lbry/extras/cli.py
|
||||
# chmod +x dist/lbrynet
|
||||
# dist/lbrynet --version
|
||||
# - if: startsWith(matrix.os, 'windows')
|
||||
# name: Build & Run (Windows)
|
||||
# run: |
|
||||
# pip install pywin32
|
||||
# pyinstaller --additional-hooks-dir=scripts/. --icon=icons/lbry256.ico --onefile --name lbrynet lbry/extras/cli.py
|
||||
# dist/lbrynet.exe --version
|
||||
|
|
20
Makefile
20
Makefile
|
@ -1,15 +1,4 @@
|
|||
.PHONY: install tools lint test idea
|
||||
|
||||
install:
|
||||
CFLAGS="-DSQLITE_MAX_VARIABLE_NUMBER=2500000" pip install -U https://github.com/rogerbinns/apsw/releases/download/3.30.1-r1/apsw-3.30.1-r1.zip \
|
||||
--global-option=fetch \
|
||||
--global-option=--version --global-option=3.30.1 --global-option=--all \
|
||||
--global-option=build --global-option=--enable --global-option=fts5
|
||||
pip install -e .
|
||||
|
||||
tools:
|
||||
pip install mypy==0.701
|
||||
pip install coverage astroid pylint
|
||||
.PHONY: tools lint test idea
|
||||
|
||||
lint:
|
||||
pylint --rcfile=setup.cfg lbry
|
||||
|
@ -21,3 +10,10 @@ test:
|
|||
idea:
|
||||
mkdir -p .idea
|
||||
cp -r scripts/idea/* .idea
|
||||
|
||||
start:
|
||||
dropdb lbry2
|
||||
createdb lbry2
|
||||
lbrynet start --full-node \
|
||||
--db-url=postgresql:///lbry2 --processes=-1 --console=advanced \
|
||||
--lbrycrd-dir=${HOME}/.lbrycrd --data-dir=/tmp/tmp-lbrynet
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
__version__ = "0.68.0"
|
||||
__version__ = "1.0.0"
|
||||
from lbry.wallet import Account, Wallet, WalletManager
|
||||
from lbry.blockchain import (
|
||||
Ledger, RegTestLedger, TestNetLedger,
|
||||
|
|
|
@ -7,7 +7,7 @@ from contextlib import contextmanager
|
|||
from typing import Tuple
|
||||
|
||||
import yaml
|
||||
from appdirs import user_data_dir, user_download_dir
|
||||
from lbry.utils.dirs import user_data_dir, user_download_dir
|
||||
from lbry.error import InvalidCurrencyError
|
||||
from lbry.dht import constants
|
||||
from lbry.wallet.coinselection import COIN_SELECTION_STRATEGIES
|
||||
|
|
192
lbry/utils/dirs.py
Normal file
192
lbry/utils/dirs.py
Normal file
|
@ -0,0 +1,192 @@
|
|||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def user_download_dir():
|
||||
r"""Return full path to the user-specific download dir.
|
||||
|
||||
Typical user data directories are:
|
||||
Mac OS X: ~/Downloads
|
||||
Unix: ~/Downloads # or in $XDG_DOWNLOAD_DIR, if defined
|
||||
Win 7: C:\Users\<username>\Downloads
|
||||
|
||||
For Unix, we follow the XDG spec and support $XDG_DOWNLOAD_DIR.
|
||||
That means, by default "~/Downloads".
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
return os.path.normpath(_get_win_download_folder())
|
||||
elif sys.platform == "darwin":
|
||||
return os.path.expanduser('~/Downloads')
|
||||
else:
|
||||
try:
|
||||
config_dirs = os.path.join(user_config_dir(), 'user-dirs.dirs')
|
||||
with open(config_dirs) as dirs_file:
|
||||
path_match = re.search(r'XDG_DOWNLOAD_DIR=(.+)', dirs_file.read())
|
||||
cleaned_path = path_match.group(1).replace('"', '').replace('$HOME', '~')
|
||||
return os.path.expanduser(cleaned_path)
|
||||
except Exception:
|
||||
pass
|
||||
return os.getenv('XDG_DOWNLOAD_DIR', os.path.expanduser("~/Downloads"))
|
||||
|
||||
|
||||
def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
||||
r"""Return full path to the user-specific data dir for this application.
|
||||
|
||||
"appname" is the name of application.
|
||||
If None, just the sys.platform directory is returned.
|
||||
"appauthor" (only used on Windows) is the name of the
|
||||
appauthor or distributing body for this application. Typically
|
||||
it is the owning company name. This falls back to appname. You may
|
||||
pass False to disable it.
|
||||
"version" is an optional version path element to append to the
|
||||
path. You might want to use this if you want multiple versions
|
||||
of your app to be able to run independently. If used, this
|
||||
would typically be "<major>.<minor>".
|
||||
Only applied when appname is present.
|
||||
"roaming" (boolean, default False) can be set True to use the Windows
|
||||
roaming appdata directory. That means that for users on a Windows
|
||||
network setup for roaming profiles, this user data will be
|
||||
sync'd on login. See
|
||||
<http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
|
||||
for a discussion of issues.
|
||||
|
||||
Typical user data directories are:
|
||||
Mac OS X: ~/Library/Application Support/<AppName>
|
||||
Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined
|
||||
Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
|
||||
Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
|
||||
Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>
|
||||
Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName>
|
||||
|
||||
For Unix, we follow the XDG spec and support $XDG_DATA_HOME.
|
||||
That means, by default "~/.local/share/<AppName>".
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
if appauthor is None:
|
||||
appauthor = appname
|
||||
const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA"
|
||||
path = os.path.normpath(_get_win_folder(const))
|
||||
if appname:
|
||||
if appauthor is not False:
|
||||
path = os.path.join(path, appauthor, appname)
|
||||
else:
|
||||
path = os.path.join(path, appname)
|
||||
elif sys.platform == "darwin":
|
||||
path = os.path.expanduser("~/Library/Application Support/")
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
else:
|
||||
path = os.getenv("XDG_DATA_HOME", os.path.expanduser("~/.local/share"))
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if appname and version:
|
||||
path = os.path.join(path, version)
|
||||
return path
|
||||
|
||||
|
||||
def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
|
||||
r"""Return full path to the user-specific config dir for this application.
|
||||
|
||||
"appname" is the name of application.
|
||||
If None, just the sys.platform directory is returned.
|
||||
"appauthor" (only used on Windows) is the name of the
|
||||
appauthor or distributing body for this application. Typically
|
||||
it is the owning company name. This falls back to appname. You may
|
||||
pass False to disable it.
|
||||
"version" is an optional version path element to append to the
|
||||
path. You might want to use this if you want multiple versions
|
||||
of your app to be able to run independently. If used, this
|
||||
would typically be "<major>.<minor>".
|
||||
Only applied when appname is present.
|
||||
"roaming" (boolean, default False) can be set True to use the Windows
|
||||
roaming appdata directory. That means that for users on a Windows
|
||||
network setup for roaming profiles, this user data will be
|
||||
sync'd on login. See
|
||||
<http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx>
|
||||
for a discussion of issues.
|
||||
|
||||
Typical user config directories are:
|
||||
Mac OS X: ~/Library/Preferences/<AppName>
|
||||
Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined
|
||||
Win *: same as user_data_dir
|
||||
|
||||
For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
|
||||
That means, by default "~/.config/<AppName>".
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
path = user_data_dir(appname, appauthor, None, roaming)
|
||||
elif sys.platform == "darwin":
|
||||
path = os.path.expanduser("~/Library/Preferences/")
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
else:
|
||||
path = os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
|
||||
if appname:
|
||||
path = os.path.join(path, appname)
|
||||
if appname and version:
|
||||
path = os.path.join(path, version)
|
||||
return path
|
||||
|
||||
|
||||
def _get_win_folder(csidl_name):
|
||||
import ctypes
|
||||
|
||||
csidl_const = {
|
||||
"CSIDL_APPDATA": 26,
|
||||
"CSIDL_COMMON_APPDATA": 35,
|
||||
"CSIDL_LOCAL_APPDATA": 28,
|
||||
}[csidl_name]
|
||||
|
||||
buf = ctypes.create_unicode_buffer(1024)
|
||||
ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
|
||||
|
||||
# Downgrade to short path name if have highbit chars. See
|
||||
# <http://bugs.activestate.com/show_bug.cgi?id=85099>.
|
||||
has_high_char = False
|
||||
for c in buf:
|
||||
if ord(c) > 255:
|
||||
has_high_char = True
|
||||
break
|
||||
if has_high_char:
|
||||
buf2 = ctypes.create_unicode_buffer(1024)
|
||||
if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024):
|
||||
buf = buf2
|
||||
|
||||
return buf.value
|
||||
|
||||
|
||||
def _get_win_download_folder():
|
||||
import ctypes
|
||||
from ctypes import windll, wintypes
|
||||
from uuid import UUID
|
||||
|
||||
class GUID(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("data1", wintypes.DWORD),
|
||||
("data2", wintypes.WORD),
|
||||
("data3", wintypes.WORD),
|
||||
("data4", wintypes.BYTE * 8)
|
||||
]
|
||||
|
||||
def __init__(self, uuidstr):
|
||||
ctypes.Structure.__init__(self)
|
||||
uuid = UUID(uuidstr)
|
||||
self.data1, self.data2, self.data3, \
|
||||
self.data4[0], self.data4[1], rest = uuid.fields
|
||||
for i in range(2, 8):
|
||||
self.data4[i] = rest >> (8-i-1)*8 & 0xff
|
||||
|
||||
SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath
|
||||
SHGetKnownFolderPath.argtypes = [
|
||||
ctypes.POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)
|
||||
]
|
||||
|
||||
FOLDERID_Downloads = '{374DE290-123F-4565-9164-39C4925E467B}'
|
||||
guid = GUID(FOLDERID_Downloads)
|
||||
pathptr = ctypes.c_wchar_p()
|
||||
|
||||
if SHGetKnownFolderPath(ctypes.byref(guid), 0, 0, ctypes.byref(pathptr)):
|
||||
raise Exception('Failed to get download directory.')
|
||||
|
||||
return pathptr.value
|
5
setup.py
5
setup.py
|
@ -39,7 +39,6 @@ setup(
|
|||
install_requires=[
|
||||
'aiohttp==3.5.4',
|
||||
'aioupnp==0.0.17',
|
||||
'appdirs==1.4.3',
|
||||
'certifi>=2018.11.29',
|
||||
'colorama==0.3.7',
|
||||
'distro==1.4.0',
|
||||
|
@ -62,7 +61,9 @@ setup(
|
|||
],
|
||||
extras_require={
|
||||
'ui': ['pyside2'],
|
||||
'postgresql': ['psycopg2']
|
||||
'postgresql': ['psycopg2'],
|
||||
'lint': ['mypy', 'pylint'],
|
||||
'test': ['coverage'],
|
||||
},
|
||||
classifiers=[
|
||||
'Framework :: AsyncIO',
|
||||
|
|
Loading…
Reference in a new issue