Browse Source

Merge branch 'pre-0.9.3'

Oz N Tiram 8 năm trước cách đây
mục cha
commit
8382a1fc6a

+ 1 - 0
.gitignore

@@ -16,3 +16,4 @@ secret.txt
 .tox
 *~
 .vagrant*
+.idea

+ 8 - 8
.travis.yml

@@ -1,6 +1,6 @@
 language: python
 python:
-  - 3.4 
+  - 3.4
   - 3.5
 
 services:
@@ -10,7 +10,7 @@ before_script:
   - psql -c "CREATE USER tester WITH PASSWORD '123456';" -U postgres
   - psql -c 'create database pwman;' -U postgres
   - psql -c 'grant ALL ON DATABASE pwman to tester' -U postgres
-  - mysql -e 'create database pwmantest' -uroot 
+  - mysql -e 'create database pwmantest' -uroot
   - mysql -e "create user 'pwman'@'localhost' IDENTIFIED BY '123456'" -uroot
   - mysql -e "grant all on pwmantest.* to 'pwman'@'localhost';" -uroot
   - mongo pwmantest --eval 'db.addUser("tester", "12345678");'
@@ -20,15 +20,15 @@ before_install:
   - sudo apt-get install python-psycopg2 python3-psycopg2
   - sudo apt-get install python-mysqldb
 # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
-install: 
-  - "pip install pymongo==2.8"  
-  - "pip install pymysql"   
+install:
+  - "pip install pymongo==2.8"
+  - "pip install pymysql"
   - "pip install -r requirements.txt -r test_requirements.txt"
   - "pip install coveralls"
   - "pip install ."
 # command to run tests, e.g. python setup.py test
-script:  
-  python setup.py develop && coverage run --source=pwman setup.py test
-    
+script:
+  python setup.py develop && coverage run -m tests.test_pwman
+
 after_success:
   coveralls

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+2017-Januar-15 Oz Nahum Tiram <oz.tiram@gmail.com>
+	* Release 0.9.3
+	* Fix multiple issues with SQLite on Windows
+	* Fix deletion of nodes
+
 2016-November-5 Oz Nahum Tiram <oz.tiram@gmail.com>
 	* Release 0.9.2
 	* Fix time out expiration

+ 2 - 3
Makefile

@@ -43,7 +43,7 @@ pre-test:
 	$(shell sudo service mysql start)
 	$(shell sudo service mongodb start)
 
-test: install clean
+test: clean install
 	python setup.py test
 	@rm -f tests/test.conf
 
@@ -51,7 +51,7 @@ test-all:
 	tox
 
 coverage-run:
-	coverage run --source pwman setup.py test
+	coverage run -m tests.test_pwman
 	coverage report -m
 	@coverage html
 
@@ -75,5 +75,4 @@ dist: clean
 	ls -l dist
 
 install:
-	pip uninstall -y pwman3
 	pip install -e .

+ 2 - 1
README.md

@@ -1,7 +1,8 @@
 # PWMAN3 
 
 [![Build Status](https://travis-ci.org/pwman3/pwman3.png?branch=master)](https://travis-ci.org/pwman3/pwman3)
-[![Coverage Status](https://coveralls.io/repos/pwman3/pwman3/badge.png)](https://coveralls.io/r/pwman3/pwman3?branch=master)
+[![Build status](https://ci.appveyor.com/api/projects/status/9yxwlj5d15bitshr?svg=true)](https://ci.appveyor.com/project/oz123/pwman3)
+[![Coverage Status](https://coveralls.io/repos/pwman3/pwman3/badge.png)](https://coveralls.io/r/pwman3/pwman3?branch=develop)
 [![Documentation Status](https://readthedocs.org/projects/pwman3/badge/?version=latest)](https://readthedocs.org/projects/pwman3/?badge=latest)
 
 A nice command line password manager, which can use different database to store your passwords (currently, SQLite, MySQL, 

+ 45 - 0
appveyor.yml

@@ -0,0 +1,45 @@
+build: false
+services:
+  - postgresql
+  - mongodb
+  - mysql
+
+environment:
+  matrix:
+    - PYTHON: "C:/Python34"
+    - PYTHON: "C:/Python35"
+    - PYTHON: "C:/Python36"
+
+  # postgres
+  POSTGRES_PATH: C:\Program Files\PostgreSQL\9.4
+  PGUSER: postgres
+  PGPASSWORD: Password12!
+
+  MYSQL_ENV_MYSQL_USER: root
+  MYSQL_ENV_MYSQL_PASSWORD: Password12!
+  MYSQL_ENV_MYSQL_DATABASE: sqlectron
+  MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.7
+  MYSQL_PWD: Password12!
+  MONGOPATH: C:/mongodb
+
+init:
+  - "ECHO %PYTHON%"
+  - ps: "ls C:/Python*"
+  - SET PATH=%MONGOPATH\bin%;%MYSQL_PATH\bin%;%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%PATH%
+
+install:
+  - "%PYTHON%/Scripts/pip.exe install -e ."
+  - "%PYTHON%/Scripts/pip.exe install -r test_requirements.txt"
+  - "%PYTHON%/Scripts/pip.exe install -r requirements.txt"
+
+test_script:
+  - C:/mongodb/bin/mongo.exe pwmantest tests/init_mongo.js
+  - psql -c "CREATE USER tester WITH PASSWORD '123456';"
+  - psql -c "create database pwman"
+  - psql -c "grant ALL ON DATABASE pwman to tester"
+  - mysql -e "create database pwmantest" -uroot
+  - mysql -e "create user 'pwman'@'localhost' IDENTIFIED BY '123456'" -uroot
+  - mysql -e "grant all on pwmantest.* to 'pwman'@'localhost';" -uroot
+  - "%PYTHON%/Scripts/pip.exe --version"
+  - "%PYTHON%/python.exe setup.py test"
+

+ 1 - 1
provision_vagrant.sh

@@ -8,7 +8,7 @@ echo "LC_ALL=en_US.UTF-8" >> /etc/environment
 echo "LANG=en_US.UTF-8" >> /etc/environment
 
 PACKAGES="python-psycopg2 sqlite3 git postgresql-server-dev-9.3 \
-python-dev python3-dev \
+python-dev python3-dev libffi-dev \
 postgresql-9.3 python3-psycopg2 mysql-server-5.6 build-essential"
 
 

+ 4 - 13
pwman/__init__.py

@@ -24,6 +24,7 @@ import os
 import pkg_resources
 import re
 import string
+import shutil
 import sys
 from pwman.util import config
 from pwman.data.factory import check_db_version
@@ -40,7 +41,7 @@ appname = "pwman3"
 try:
     version = pkg_resources.get_distribution('pwman3').version
 except pkg_resources.DistributionNotFound:  # pragma: no cover
-    version = "0.9.1"
+    version = "0.9.3"
 
 
 class PkgMetadata(object):
@@ -68,16 +69,6 @@ except IOError as E:
     website = 'http://pwman3.github.io/pwman3/'
 
 
-def which(cmd):  # pragma: no cover
-    _, cmdname = os.path.split(cmd)
-
-    for path in os.environ["PATH"].split(os.pathsep):
-        cmd = os.path.join(path, cmdname)
-        if os.path.isfile(cmd) and os.access(cmd, os.X_OK):  # pragma: no cover
-            return cmd
-    return ''
-
-
 config_dir = os.path.expanduser("~/.pwman")
 
 
@@ -106,10 +97,10 @@ def get_conf(args):
 
 def set_xsel(configp, OSX):
     if not OSX:
-        xselpath = which("xsel")
+        xselpath = shutil.which("xsel") or ""
         configp.set_value("Global", "xsel", xselpath)
     elif OSX:
-        pbcopypath = which("pbcopy")
+        pbcopypath = shutil.which("pbcopy") or ""
         configp.set_value("Global", "xsel", pbcopypath)
 
 

+ 9 - 1
pwman/data/drivers/sqlite.py

@@ -40,6 +40,9 @@ class SQLite(Database):
         cur = con.cursor()
         cur.execute("PRAGMA TABLE_INFO(DBVERSION)")
         row = cur.fetchone()
+        cur.close()
+        con.close()
+
         try:
             return row[-2]
         except TypeError:
@@ -57,7 +60,12 @@ class SQLite(Database):
         self._data_wrapper = lambda x: x
 
     def _open(self):
-        self._con = sqlite.connect(self._filename)
+        try:
+            self._con = sqlite.connect(self._filename)
+        except sqlite.OperationalError as E:
+            print("could not open %s" % self._filename)
+            raise E
+
         self._cur = self._con.cursor()
         self._create_tables()
 

+ 4 - 1
pwman/data/factory.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2012-2015 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2012-2016 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 
 import sys
@@ -30,6 +30,9 @@ from pwman.data import drivers
 
 
 def parse_sqlite_uri(dburi):
+    """return dburi.netloc if on windows, because this was someone break"""
+    if not dburi.path:
+        return dburi.netloc
     filename = os.path.abspath(dburi.path)
     return filename
 

+ 21 - 15
pwman/ui/baseui.py

@@ -14,16 +14,17 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2013, 2014 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2013-2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
-from __future__ import print_function
-import sys
-import os
 import ast
 import csv
-import time
+import os
 import re
 import select as uselect
+import shutil
+import sys
+import time
+
 from colorama import Fore
 from pwman.data.nodes import Node
 from pwman.ui import tools
@@ -203,6 +204,8 @@ class BaseUtilsMixin:
                 ids.append(int(begin))
         else:
             print("Could not understand your input...")
+            return ids
+
         return ids
 
     def _get_tags(self, default=None, reader=raw_input):
@@ -221,11 +224,7 @@ class BaseUtilsMixin:
 
     def _prep_term(self):
         self.do_cls('')
-        if sys.platform != 'win32':
-            rows, cols = tools.gettermsize()
-        else:  # pragma: no cover
-            rows, cols = 18, 80  # fix this !
-
+        rows, cols = shutil.get_terminal_size()
         return rows, cols
 
     def _format_line(self, tag_pad, nid="ID", user="USER", url="URL",
@@ -354,15 +353,15 @@ class BaseCommands(HelpUIMixin, AliasesMixin, BaseUtilsMixin):
             if re.search(r'^\d{4}$', umask):
                 os.umask(int(umask))
 
+    def do_cls(self, args):  # pragma: no cover
+        """clear the screen"""
+        os.system("clear")
+
     def do_exit(self, args):  # pragma: no cover
         """close the text console"""
         self._db.close()
         return True
 
-    def do_cls(self, args):  # pragma: no cover
-        """clear the screen"""
-        os.system("clear")
-
     def do_export(self, args):
         """export the database to a given format"""
         try:
@@ -374,6 +373,7 @@ class BaseCommands(HelpUIMixin, AliasesMixin, BaseUtilsMixin):
         delim = args.get('delimiter', ';')
         nodeids = self._db.listnodes()
         nodes = self._db.getnodes(nodeids)
+
         with open(filename, 'w') as csvfile:
             writer = csv.writer(csvfile, delimiter=delim)
             writer.writerow(['Username', 'URL', 'Password', 'Notes',
@@ -387,6 +387,10 @@ class BaseCommands(HelpUIMixin, AliasesMixin, BaseUtilsMixin):
                 r = list([n.username, n.url, n.password, n.notes])
                 writer.writerow(r + [tags])
 
+        with open(filename) as f:
+            for line in f.readlines():
+                print(line)
+
         print("Successfuly exported database to {}".format(
             os.path.join(os.getcwd(), filename)))
 
@@ -478,11 +482,13 @@ class BaseCommands(HelpUIMixin, AliasesMixin, BaseUtilsMixin):
 
     def do_delete(self, args):
         ids = self._get_ids(args)
+        if not ids:
+            return
         ans = tools.getinput("Are you sure you want to delete node{} {}"
                              " [y/N]?".format("s" if len(ids) > 1 else "",
                                               ",".join(ids) if len(ids) > 1 else ids[0]))  # noqa
         if ans.lower() == 'y':
-            self._do_rm(args)
+            self._do_rm(ids)
 
     def do_info(self, args):
         print("Currently connected to: {}".format(

+ 0 - 18
pwman/ui/mac.py

@@ -51,21 +51,3 @@ class PwmanCliMac(PwmanCli):
             print("erasing in {} sec...".format(flushtimeout))
             time.sleep(int(flushtimeout))
             tools.text_to_mcclipboard("")
-
-    def do_open(self, args):
-        ids = self._get_ids(args)
-        if not args:
-            self.help_open()
-            return
-        if len(ids) > 1:
-            print("Can open only 1 link at a time ...")
-            return None
-
-        ce = CryptoEngine.get()
-        nodes = self._db.getnodes(ids)
-
-        for node in nodes:
-            url = ce.decrypt(node[3])
-            if not url.startswith(("http://", "https://")):
-                url = "https://" + url
-            tools.open_url(url, macosx=True)

+ 7 - 100
pwman/ui/tools.py

@@ -14,12 +14,12 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2013 Oz Nahum <nahumoz@gmail.com>
+# Copyright (C) 2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 """
 Define the CLI interface for pwman3 and the helper functions
 """
-from __future__ import print_function
+
 import subprocess as sp
 import getpass
 import sys
@@ -120,108 +120,15 @@ def text_to_mcclipboard(text):  # pragma: no cover
         print (e, "\nExecuting pbcoy failed...")
 
 
-def open_url(link, macosx=False, ):  # pragma: no cover
+def open_url(link, macosx=False,):  # pragma: no cover
     """
     launch xdg-open or open in MacOSX with url
     """
-    uopen = "xdg-open "
-    if macosx:
-        uopen = "open "
-    try:
-        sp.call(uopen + link, shell=True, stdout=sp.PIPE, stderr=sp.PIPE)
-    except OSError as e:
-        print("Executing open_url failed with:\n", e)
-
-
-def get_terminal_size():  # pragma: no cover
-    """ getTerminalSize()
-     - get width and height of console
-     - works on linux,os x,windows,cygwin(windows)
-     originally retrieved from:
-     http://stackoverflow.com/questions/566746/how-to-get-\
-         console-window-width-in-python
-    """
-    current_os = platform.system()
-    tuple_xy = None
-    if current_os == 'Windows':
-        tuple_xy = _get_terminal_size_windows()
-        if tuple_xy is None:
-            tuple_xy = _get_terminal_size_tput()
-            # needed for window's python in cygwin's xterm!
-    if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'):
-        tuple_xy = _get_terminal_size_linux()
-    if tuple_xy is None:
-        tuple_xy = (80, 25)      # default value
-    return tuple_xy
-
-
-def _get_terminal_size_windows():  # pragma: no cover
-    try:
-        from ctypes import windll, create_string_buffer
-        # stdin handle is -10
-        # stdout handle is -11
-        # stderr handle is -12
-        h = windll.kernel32.GetStdHandle(-12)
-        csbi = create_string_buffer(22)
-        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
-        if res:
-            (bufx, bufy, curx, cury, wattr,
-             left, top, right, bottom,
-             maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
-            sizex = right - left + 1
-            sizey = bottom - top + 1
-            return sizex, sizey
-    except:
-        pass
-
-
-def _get_terminal_size_tput():  # pragma: no cover
-    # get terminal width
-    # src: http://stackoverflow.com/questions/263890/how-do-i-\
-    #    find-the-width-height-of-a-terminal-window
+    import webbrowser
     try:
-        cols = int(sp.check_call(shlex.split('tput cols')))
-        rows = int(sp.check_call(shlex.split('tput lines')))
-        return (cols, rows)
-    except:
-        pass
-
-
-def _get_terminal_size_linux():  # pragma: no cover
-    def ioctl_GWINSZ(fd):
-        try:
-            import fcntl
-            import termios
-            cr = struct.unpack('hh',
-                               fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
-            return cr
-        except:
-            pass
-    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
-    if not cr:
-        try:
-            fd = os.open(os.ctermid(), os.O_RDONLY)
-            cr = ioctl_GWINSZ(fd)
-            os.close(fd)
-        except:
-            pass
-    if not cr:
-        try:
-            cr = (os.environ['LINES'], os.environ['COLUMNS'])
-        except:
-            return None
-    return int(cr[1]), int(cr[0])
-
-
-def gettermsize():  # pragma: no cover
-    if sys.stdout.isatty():
-        s = struct.pack("HHHH", 0, 0, 0, 0)
-        f = sys.stdout.fileno()
-        x = fcntl.ioctl(f, termios.TIOCGWINSZ, s)
-        rows, cols, width, height = struct.unpack("HHHH", x)
-        return rows, cols
-    else:
-        return 40, 80
+        webbrowser.open(link)
+    except webbrowser.Error as E:
+         print("Executing open_url failed with:\n", e)
 
 
 def getinput(question, default="", reader=raw_input,

+ 1 - 19
pwman/ui/win.py

@@ -67,7 +67,7 @@ def winGetClipboard():
 
 
 def winSetClipboard(text):
-    
+
     GMEM_DDESHARE = 0x2000
     ctypes.windll.user32.OpenClipboard(0)
     ctypes.windll.user32.EmptyClipboard()
@@ -119,23 +119,5 @@ class PwmanCliWin(PwmanCli):
             time.sleep(int(flushtimeout))
             winSetClipboard(b"")
 
-    def do_open(self, args):
-        ids = self._get_ids(args)
-        if not args:
-            self.help_open()
-            return
-        if len(ids) > 1:
-            print ("Can open only 1 link at a time ...")
-            return None
-
-        ce = CryptoEngine.get()
-        nodes = self._db.getnodes(ids)
-
-        for node in nodes:
-            url = ce.decrypt(node[3])
-            if not url.startswith(("http://", "https://")):
-                url = "https://" + url
-            os.system("start "+url)
-
     def do_cls(self, args):
         os.system('cls')

+ 20 - 3
setup.py

@@ -54,6 +54,23 @@ add to your ```setup.cfg``` the following::
 
 # build.sub_commands.append(('build_manpage', None))
 
+class TestCommand(Command):
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        import sys, subprocess
+
+        raise SystemExit(
+            subprocess.call([sys.executable,
+                             '-m',
+                             'tests.test_pwman']))
+
 
 class BuildManPage(Command):
 
@@ -310,7 +327,7 @@ packages = find_packages(exclude=['tests', 'pwman/ui/templates'])
 
 
 setup(name='pwman3',
-      version='0.9.2',
+      version='0.9.3',
       description=("a command line password manager with support for multiple"
                    " databases."),
       long_description=long_description,
@@ -337,9 +354,9 @@ setup(name='pwman3',
                    'Programming Language :: Python :: 3.4',
                    'Programming Language :: Python :: 3.5',
                    ],
-      test_suite='tests.test_pwman.suite',
       cmdclass={
-          'build_manpage': BuildManPage
+          'build_manpage': BuildManPage,
+          'test': TestCommand
       },
       entry_points={
           'console_scripts': ['pwman3 = pwman.ui.cli:main']

+ 2 - 1
tests/db_tests.py

@@ -53,7 +53,8 @@ _saveconfig = False
 from .test_tools import (SetupTester)  # DummyCallback2,
                          #  DummyCallback3, DummyCallback4)
 
-testdb = os.path.join(os.path.dirname(__file__), "test.pwman.db")
+db =  ".".join(("pwman","test", sys.version.split(" " ,1)[0], "db"))
+testdb = os.path.abspath(os.path.join(os.path.dirname(__file__), db))
 
 
 class CLITests(unittest.TestCase):

+ 0 - 2
tests/init_mongo.js

@@ -1,7 +1,5 @@
 // run this script with $ mongo < init_mongo.js
 
-use pwmantest
-
 db.createUser({user: "tester", pwd: "12345678",
               roles: [{role: "dbAdmin", db: "pwmantest"},
                       {role: "readWrite", db: "pwmantest"},]

+ 12 - 10
tests/test_base_ui.py

@@ -18,19 +18,16 @@
 # ============================================================================
 import os
 import unittest
+import sys
 from io import StringIO, BytesIO
 
-import sys
 from pwman.util.crypto_engine import CryptoEngine
 from .test_crypto_engine import give_key, DummyCallback
 from pwman.data.database import __DB_FORMAT__
-from .test_tools import (SetupTester)
+from .test_tools import (SetupTester, testdb)
 from pwman.data import factory
 from pwman.data.nodes import Node
 
-testdb = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                      "test-baseui.pwman.db"))
-
 
 class dummy_stdin(object):
 
@@ -62,6 +59,10 @@ class TestBaseUI(unittest.TestCase):
         self.tester = SetupTester(dbver, testdb)
         self.tester.create()
 
+    def tearDown(self):
+        #self.tester.cli.do_exit("")
+        pass
+
     def test_get_tags(self):
         sys.stdin = StringIO("foo bar baz\n")
         tags = self.tester.cli._get_tags(reader=lambda: "foo bar baz")
@@ -99,12 +100,14 @@ class TestBaseUI(unittest.TestCase):
         self.tester.cli.do_export("{'filename':'foo.csv'}")
         with open('foo.csv') as f:
             l = f.readlines()
-
-        self.assertIn('alice;example.com;secret;some notes;foo,bar,baz', l[1])
+        # on windows there is an extra empty line in the exported file
+        self.assertIn('alice;example.com;secret;some notes;foo,bar,baz\n', l)
+    def test_3a_do_export(self):
         self.tester.cli.do_export("f")
         with open('pwman-export.csv') as f:
             l = f.readlines()
-        self.assertIn('alice;example.com;secret;some notes;foo,bar,baz', l[1])
+
+        self.assertIn('alice;example.com;secret;some notes;foo,bar,baz\n', l)
 
     def test_4_do_forget(self):
         self.tester.cli.do_forget('')
@@ -129,7 +132,6 @@ class TestBaseUI(unittest.TestCase):
         for t in ['foo', 'bar', 'baz']:
             t in v
         sys.stdout = sys.__stdout__
-        print(v)
 
     def test_7_get_ids(self):
         # used by do_cp or do_open,
@@ -179,7 +181,7 @@ class TestBaseUI(unittest.TestCase):
         self.output = StringIO()
         sys.stdout = self.output
         self.tester.cli.do_info(b'')
-        self.assertIn("test.pwman.db", sys.stdout.getvalue())
+        self.assertIn(testdb, sys.stdout.getvalue())
 
 if __name__ == '__main__':
 

+ 3 - 2
tests/test_complete_ui.py

@@ -18,11 +18,12 @@
 # ============================================================================
 # pylint: disable=I0011
 from __future__ import print_function
+
 import pexpect
 import unittest
+import shutil
 import sys
 import os
-from pwman import which
 
 class Ferrum(unittest.TestCase):
     def clean_files(self):
@@ -60,7 +61,7 @@ class Ferrum(unittest.TestCase):
     def test_c_change_pass(self):
         lfile = 'test-chg_passwd.log'
         logfile = open(lfile, 'wb')
-        cmd = which('pwman3')
+        cmd = shutil.which('pwman3')
         db = 'sqlite://' + os.path.join(os.path.dirname(__file__), 'foo.baz.db')
         child = pexpect.spawn(cmd + ' -d ' + db, logfile=logfile)
         if sys.version_info[0] > 2:

+ 3 - 2
tests/test_config.py

@@ -64,8 +64,9 @@ class TestConfig(unittest.TestCase):
     #                                                     'algorithm'))
 
     def test_has_user_history(self):
-        self.assertEqual(os.path.expanduser('~/.pwman/history'),
-                         self.conf.get_value('Readline', 'history'))
+        path = os.path.expanduser(os.path.join("~/.pwman", "history"))
+        config =self.conf.get_value('Readline', 'history')
+        self.assertEqual(path, config)
 
     def test_has_user_db(self):
         self.assertNotEqual(os.path.expanduser('~/.pwman/pwman.db'),

+ 1 - 1
tests/test_converter.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2012 Oz Nahum <nahumoz@gmail.com>
+# Copyright (C) 2012-2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 # pylint: disable=I0011
 from __future__ import print_function

+ 7 - 5
tests/test_factory.py

@@ -14,13 +14,14 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2013-2014 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2013-2017 Oz Nahum Tiram <nahumoz@gmail.com>
 # ============================================================================
 
-import sys
-import unittest
 import os
 import os.path
+import unittest
+import sys
+
 from pwman.data import factory
 from pwman.data.database import DatabaseException
 from pwman.data.drivers.sqlite import SQLite
@@ -28,8 +29,9 @@ from pwman.data.drivers.postgresql import PostgresqlDatabase
 from pwman.data.database import __DB_FORMAT__
 from .test_tools import (SetupTester)
 
-testdb = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                      "test.pwman.db"))
+db =  ".".join(("pwman","test", sys.version.split(" " ,1)[0], "db"))
+testdb = os.path.abspath(os.path.join(os.path.dirname(__file__), db))
+
 _saveconfig = False
 
 

+ 9 - 2
tests/test_importer.py

@@ -14,10 +14,12 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2012, 2013, 2014 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2012-2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 import os
 import unittest
+import sys
+
 from collections import namedtuple
 import pwman.data.factory
 from pwman.util.crypto_engine import CryptoEngine
@@ -94,7 +96,12 @@ class TestImporter(unittest.TestCase):
         if os.path.exists('importdummy.db'):
             os.unlink('importdummy.db')
         args = Args(file_delim=['import_file.csv', ';'], db='importdummy.db')
-        db = pwman.data.factory.createdb('sqlite:///' + os.getcwd() +
+        p = os.getcwd()
+        if sys.platform.startswith("win"):
+            p = p.strip("C:\\")
+            print(os.getcwd())
+
+        db = pwman.data.factory.createdb('sqlite:///' + p +
                                          '/importdummy.db', 0.6)
         importer = Importer((args, '', db))
         importer.importer.run(callback=DummyCallback)

+ 16 - 6
tests/test_init.py

@@ -16,15 +16,19 @@
 # ============================================================================
 # Copyright (C) 2014 Oz Nahum Tiram <nahumoz@gmail.com>
 # ============================================================================
-import unittest
-from collections import namedtuple
 import os
 import os.path
+import unittest
+import sys
+
+from collections import namedtuple
+
 from pwman import set_xsel
 from pwman.data import factory
 from pwman.data.database import __DB_FORMAT__
 from pwman import (get_conf, get_conf_options, get_db_version)
 from .test_tools import SetupTester
+
 dummyfile = """
 [Encryption]
 
@@ -38,8 +42,8 @@ cls_timeout = 5
 [Database]
 """
 
-testdb = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                      "test.pwman.db"))
+db =  ".".join(("pwman","test", sys.version.split(" " ,1)[0], "db"))
+testdb = os.path.abspath(os.path.join(os.path.dirname(__file__), db))
 
 
 class TestFactory(unittest.TestCase):
@@ -61,7 +65,7 @@ class TestInit(unittest.TestCase):
         for item in ('dummy.cfg', testdb):
             try:
                 os.unlink(item)
-            except OSError:
+            except (OSError, PermissionError):
                 continue
 
     def setUp(self):
@@ -72,12 +76,18 @@ class TestInit(unittest.TestCase):
         self.tester = SetupTester(__DB_FORMAT__, dburi=testdb)
         self.tester.create()
 
+    def tearDown(self):
+        del(self.tester)
+        try:
+            os.unlink(self.db._filename)
+        except PermissionError:
+            pass
+
     def test_get_db_version(self):
         v = get_db_version(self.tester.configp, 'sqlite')
         self.assertEqual(v, u"'0.6'")
         v = get_db_version(self.tester.configp, 'sqlite')
         self.assertEqual(v, u"'0.6'")
-        os.unlink(testdb)
 
     def test_set_xsel(self):
         Args = namedtuple('args', 'cfile, dbase, algo')

+ 1 - 1
tests/test_mongodb.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2015 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2015-2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 
 import unittest

+ 1 - 1
tests/test_nodes.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2014 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2014-2017 Oz Nahum Tiram <oz.tiram@gmail.com>
 # ============================================================================
 import unittest
 from pwman.util.crypto_engine import CryptoEngine

+ 1 - 1
tests/test_postgresql.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2015 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2015-2017 Oz Nahum Tiram <nahumoz@gmail.com>
 # ============================================================================
 import unittest
 import sys

+ 1 - 1
tests/test_pwman.py

@@ -15,7 +15,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2013 Oz Nahum <nahumoz@gmail.com>
+# Copyright (C) 2013-2017 Oz Nahum <nahumoz@gmail.com>
 # ============================================================================
 
 import os

+ 1 - 1
tests/test_sqlite.py

@@ -14,7 +14,7 @@
 # along with Pwman3; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # ============================================================================
-# Copyright (C) 2012, 2013, 2014 Oz Nahum Tiram <nahumoz@gmail.com>
+# Copyright (C) 2012-2017 Oz Nahum Tiram <nahumoz@gmail.com>
 # ============================================================================
 import os
 import unittest

+ 16 - 16
tests/test_tools.py

@@ -1,6 +1,8 @@
 import os
 import os.path
+import shutil
 import sys
+
 if sys.version_info.major > 2:  # pragma: no cover
     from urllib.parse import urlparse
 else:
@@ -8,7 +10,6 @@ else:
 
 from pwman.data import factory
 from pwman.util import config
-from pwman import which
 from pwman.util.callback import Callback
 
 
@@ -64,15 +65,13 @@ class DummyCallback4(Callback):
     def getsecret(self, question):
         return b'newsecret'
 
+db =  ".".join(("pwman","test", sys.version.split(" " ,1)[0], "db"))
+testdb = os.path.abspath(os.path.join(os.path.dirname(__file__), db))
 
 config.default_config['Database'] = {'type': 'sqlite',
-                                     'filename':
-                                     os.path.join(os.path.dirname(__file__),
-                                                  "test.pwman.db"),
+                                     'filename': testdb,
                                      'dburi': os.path.join(
-                                         'sqlite:///',
-                                         os.path.dirname(__file__),
-                                         "test.pwman.db")
+                                         'sqlite:///', testdb)
                                      }
 
 dc = """
@@ -99,13 +98,11 @@ class SetupTester(object):
                                      config.default_config)
 
         self.configp.set_value('Database', 'dburi',
-                               'sqlite://' + os.path.join(
-                                   os.path.abspath(os.path.dirname(__file__)),
-                                   "test.pwman.db")
+                               'sqlite://' + testdb
                                )
 
         if not OSX:
-            self.xselpath = which("xsel")
+            self.xselpath = shutil.which("xsel") or ""
             self.configp.set_value("Global", "xsel", self.xselpath)
         else:
             self.xselpath = "xsel"
@@ -116,11 +113,14 @@ class SetupTester(object):
     def clean(self):
         dbfile = self.configp.get_value('Database', 'filename')
         dburi = urlparse(self.configp.get_value('Database', 'dburi')).path
-        if os.path.exists(dbfile):
-            os.remove(dbfile)
-
-        if os.path.exists(dburi):
-            os.remove(dburi)
+        try:
+            if os.path.exists(dbfile):
+                os.remove(dbfile)
+
+            if os.path.exists(dburi):
+                os.remove(dburi)
+        except PermissionError:
+            pass
 
         if os.path.exists(os.path.join(os.path.dirname(__file__),
                                        'testing_config')):