Browse Source

Linting and tests

Peter Magnusson 8 years ago
parent
commit
acfe2dacc8

+ 2 - 1
.gitignore

@@ -1,4 +1,4 @@
-# python-stuff 
+# python-stuff
 *.egg-info/
 .eggs
 dist/
@@ -8,6 +8,7 @@ build/
 # testing
 .coverage
 env/
+*.log
 
 # editors
 .vscode/

File diff suppressed because it is too large
+ 0 - 61
.pylintrc


+ 17 - 0
doc/TEST.md

@@ -0,0 +1,17 @@
+Testing nodemcu-uploader
+========================
+
+```
+pip install -r test_requirements.txt
+coverage run setup.py test
+```
+
+To run tests that actually communicate with a device you
+will need to set the __SERIALPORT__ environment variable
+to the port where you have an device connected.
+
+Linux
+```
+export SERIALPORT=/dev/ttyUSB0
+```
+

+ 2 - 1
nodemcu-uploader.py

@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
-from lib import main
+"""makes it easier to run nodemcu-uploader from command line"""
+from nodemcu_uploader import main
 
 
 if __name__ == '__main__':

+ 1 - 1
nodemcu_uploader/__init__.py

@@ -5,4 +5,4 @@
 """Library and util for uploading files to NodeMCU version 0.9.4 and later"""
 
 from .version import __version__
-from .uploader import Uploader
+from .uploader import Uploader

+ 6 - 3
nodemcu_uploader/exceptions.py

@@ -1,10 +1,13 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+#pylint: disable=C0111
+
+"""Various custom exceptions"""
 
 class CommunicationTimeout(Exception):
-    def __init__(self, message, buffer):
+    def __init__(self, message, buf):
         super(CommunicationTimeout, self).__init__(message)
-        self.buffer = buffer
+        self.buf = buf
 
 
 class BadResponseException(Exception):
@@ -17,4 +20,4 @@ class BadResponseException(Exception):
 
 
 class DeviceNotFoundException(Exception):
-    pass
+    pass

+ 5 - 4
nodemcu_uploader/luacode.py

@@ -1,11 +1,12 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
+"""This module contains all the LUA code that needs to be on the device
+to perform whats needed. They will be uploaded if they doesn't exist"""
+
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+# pylint: disable=C0301
 
 
-# these functions are needed on the device, otherwise they will be
-# uploaded during prepare
-LUA_FUNCTIONS = ['recv_block', 'recv_name','recv','shafile', 'send_block', 'send_file', 'send']
+LUA_FUNCTIONS = ['recv_block', 'recv_name', 'recv', 'shafile', 'send_block', 'send_file', 'send']
 
 DOWNLOAD_FILE = "file.open('{filename}') print(file.seek('end', 0)) file.seek('set', {bytes_read}) uart.write(0, file.read({chunk_size}))file.close()"
 

+ 34 - 28
nodemcu_uploader/main.py

@@ -1,7 +1,9 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
 
+"""This module is the cli for the Uploader class"""
+
+
 import argparse
 import logging
 import os
@@ -10,7 +12,7 @@ from .uploader import Uploader
 from .term import terminal
 from serial import VERSION as serialversion
 
-log = logging.getLogger(__name__)
+log = logging.getLogger(__name__) # pylint: disable=C0103
 from .version import __version__
 
 def destination_from_source(sources):
@@ -23,17 +25,17 @@ def destination_from_source(sources):
     destinations = []
     newsources = []
     for i in range(0, len(sources)):
-        sd = sources[i].split(':')
-        if len(sd) == 2:
-            destinations.append(sd[1])
-            newsources[i] = sd[0]
+        srcdst = sources[i].split(':')
+        if len(srcdst) == 2:
+            destinations.append(srcdst[1])
+            newsources[i] = srcdst[0]
         else:
-            listing = glob.glob(sd[0])
+            listing = glob.glob(srcdst[0])
             for filename in listing:
                 newsources.append(filename)
                 #always use forward slash at destination
                 destinations.append(filename.replace('\\', '/'))
-            
+
     return [newsources, destinations]
 
 
@@ -42,17 +44,18 @@ def operation_upload(uploader, sources, verify, do_compile, do_file, do_restart)
     sources, destinations = destination_from_source(sources)
     if len(destinations) == len(sources):
         if uploader.prepare():
-            for f, d in zip(sources, destinations):
+            for filename, dst in zip(sources, destinations):
                 if do_compile:
-                    uploader.file_remove(os.path.splitext(d)[0]+'.lc')
-                uploader.write_file(f, d, verify)
-                if do_compile and d != 'init.lua':
-                    uploader.file_compile(d)
-                    uploader.file_remove(d)
+                    uploader.file_remove(os.path.splitext(dst)[0]+'.lc')
+                uploader.write_file(filename, dst, verify)
+                #init.lua is not allowed to be compiled
+                if do_compile and dst != 'init.lua':
+                    uploader.file_compile(dst)
+                    uploader.file_remove(dst)
                     if do_file:
-                        uploader.file_do(os.path.splitext(d)[0]+'.lc')
+                        uploader.file_do(os.path.splitext(dst)[0]+'.lc')
                 elif do_file:
-                    uploader.file_do(d)
+                    uploader.file_do(dst)
         else:
             raise Exception('Error preparing nodemcu for reception')
     else:
@@ -67,8 +70,8 @@ def operation_download(uploader, sources):
     """The download operation"""
     destinations = destination_from_source(sources)
     if len(destinations) == len(sources):
-        for f, d in zip(sources, destinations):
-            uploader.read_file(f, d)
+        for filename, dst in zip(sources, destinations):
+            uploader.read_file(filename, dst)
     else:
         raise Exception('You must specify a destination filename for each file you want to download.')
     log.info('All done!')
@@ -79,16 +82,16 @@ def operation_file(uploader, cmd, filename=''):
     if cmd == 'list':
         uploader.file_list()
     if cmd == 'do':
-        for f in filename:
-            uploader.file_do(f)
+        for path in filename:
+            uploader.file_do(path)
     elif cmd == 'format':
         uploader.file_format()
     elif cmd == 'remove':
-        for f in filename:
-            uploader.file_remove(f)
+        for path in filename:
+            uploader.file_remove(path)
     elif cmd == 'print':
-        for f in filename:
-            uploader.file_print(f)
+        for path in filename:
+            uploader.file_print(path)
 
 
 
@@ -98,6 +101,7 @@ def arg_auto_int(value):
 
 
 def main_func():
+    """Main function for cli"""
     parser = argparse.ArgumentParser(
         description='NodeMCU Lua file uploader',
         prog='nodemcu-uploader'
@@ -187,7 +191,9 @@ def main_func():
         'download',
         help='Path to one or more files to be downloaded. Destination name will be the same as the file name.')
 
-    download_parser.add_argument('filename', nargs='+', help='Lua file to download. Use colon to give alternate destination.')
+    download_parser.add_argument('filename',
+        nargs='+',
+        help='Lua file to download. Use colon to give alternate destination.')
 
 
     file_parser = subparsers.add_parser(
@@ -207,7 +213,7 @@ def main_func():
 
     node_parse.add_argument('ncmd', choices=('heap', 'restart'), help="heap=print heap memory, restart=restart nodemcu")
 
-    terminal_parser = subparsers.add_parser(
+    subparsers.add_parser(
         'terminal',
         help='Run pySerials miniterm'
     )
@@ -238,8 +244,8 @@ def main_func():
 
     elif args.operation == 'exec':
         sources = args.filename
-        for f in sources:
-            uploader.exec_file(f)
+        for path in sources:
+            uploader.exec_file(path)
 
     elif args.operation == 'file':
         operation_file(uploader, args.cmd, args.filename)

+ 118 - 98
nodemcu_uploader/uploader.py

@@ -1,6 +1,6 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+"""Main functionality for nodemcu-uploader"""
 
 import time
 import logging
@@ -8,19 +8,21 @@ import hashlib
 import os
 import serial
 
-from .exceptions import CommunicationTimeout, DeviceNotFoundException, BadResponseException
+from .exceptions import CommunicationTimeout, DeviceNotFoundException
+from .exceptions import BadResponseException
 from .utils import default_port, system
-from .luacode import DOWNLOAD_FILE, RECV_LUA, SEND_LUA, LUA_FUNCTIONS, LIST_FILES, UART_SETUP, PRINT_FILE
+from .luacode import LUA_FUNCTIONS, DOWNLOAD_FILE, RECV_LUA, SEND_LUA, LIST_FILES, UART_SETUP, PRINT_FILE
 
-log = logging.getLogger(__name__)
+log = logging.getLogger(__name__) # pylint: disable=C0103
 
 __all__ = ['Uploader', 'default_port']
 
 SYSTEM = system()
 
-BLOCK_START='\x01';
-NUL = '\x00';
-ACK = '\x06';
+MINIMAL_TIMEOUT = 0.0001
+BLOCK_START = '\x01'
+NUL = '\x00'
+ACK = '\x06'
 
 class Uploader(object):
     """Uploader is the class for communicating with the nodemcu and
@@ -46,30 +48,31 @@ class Uploader(object):
         self._port.setRTS(False)
         self._port.setDTR(False)
 
-        def sync():
-            # Get in sync with LUA (this assumes that NodeMCU gets reset by the previous two lines)
-            log.debug('getting in sync with LUA');
-            self.clear_buffers()
+        def __sync():
+            """Get in sync with LUA (this assumes that NodeMCU gets reset by the previous two lines)"""
+            log.debug('getting in sync with LUA')
+            self.__clear_buffers()
             try:
-                self.exchange(';') # Get a defined state
-                self.writeln('print("%sync%");')
-                self.expect('%sync%\r\n> ')
+                self.__exchange(';') # Get a defined state
+                self.__writeln('print("%sync%");')
+                self.__expect('%sync%\r\n> ')
             except CommunicationTimeout:
                 raise DeviceNotFoundException('Device not found or wrong port')
 
-        sync()
+        __sync()
 
         if baud != start_baud:
-            self.set_baudrate(baud)
+            self.__set_baudrate(baud)
 
             # Get in sync again
-            sync()
+            __sync()
 
         self.line_number = 0
 
-    def set_baudrate(self, baud):
+    def __set_baudrate(self, baud):
+        """setting baudrate if supported"""
         log.info('Changing communication to %s baud', baud)
-        self.writeln(UART_SETUP.format(baud=baud))
+        self.__writeln(UART_SETUP.format(baud=baud))
         # Wait for the string to be sent before switching baud
         time.sleep(0.1)
         try:
@@ -79,7 +82,8 @@ class Uploader(object):
             self._port.baudrate = baud
 
 
-    def clear_buffers(self):
+    def __clear_buffers(self):
+        """Clears the input and output buffers"""
         try:
             self._port.reset_input_buffer()
             self._port.reset_output_buffer()
@@ -89,16 +93,14 @@ class Uploader(object):
             self._port.flushOutput()
 
 
-    def expect(self, exp='> ', timeout=TIMEOUT):
+    def __expect(self, exp='> ', timeout=TIMEOUT):
         """will wait for exp to be returned from nodemcu or timeout"""
+        timer = self._port.timeout
         #do NOT set timeout on Windows
         if SYSTEM != 'Windows':
-            timer = self._port.timeout
-
             # Checking for new data every 100us is fast enough
-            lt = 0.0001
-            if self._port.timeout != lt:
-                self._port.timeout = lt
+            if self._port.timeout != MINIMAL_TIMEOUT:
+                self._port.timeout = MINIMAL_TIMEOUT
 
         end = time.time() + timeout
 
@@ -119,7 +121,7 @@ class Uploader(object):
 
         return data
 
-    def write(self, output, binary=False):
+    def __write(self, output, binary=False):
         """write data on the nodemcu port. If 'binary' is True the debug log
         will show the intended output as hex, otherwise as string"""
         if not binary:
@@ -129,23 +131,24 @@ class Uploader(object):
         self._port.write(output)
         self._port.flush()
 
-    def writeln(self, output):
+    def __writeln(self, output):
         """write, with linefeed"""
-        self.write(output + '\n')
+        self.__write(output + '\n')
 
-    def exchange(self, output, timeout=TIMEOUT):
-        self.writeln(output)
+    def __exchange(self, output, timeout=TIMEOUT):
+        """Write output to the port and wait for response"""
+        self.__writeln(output)
         self._port.flush()
-        return self.expect(timeout=timeout)
+        return self.__expect(timeout=timeout)
 
 
     def close(self):
         """restores the nodemcu to default baudrate and then closes the port"""
         try:
             if self.baud != self.start_baud:
-                self.set_baudrate(self.start_baud)
+                self.__set_baudrate(self.start_baud)
             self._port.flush()
-            self.clear_buffers()
+            self.__clear_buffers()
         except serial.serialutil.SerialException:
             pass
         log.debug('closing port')
@@ -159,9 +162,9 @@ class Uploader(object):
         """
         log.info('Preparing esp for transfer.')
 
-        for fn in LUA_FUNCTIONS:
-            d = self.exchange('print({0})'.format(fn))
-            if d.find('function:') == -1:
+        for func in LUA_FUNCTIONS:
+            detected = self.__exchange('print({0})'.format(func))
+            if detected.find('function:') == -1:
                 break
         else:
             log.info('Preparation already done. Not adding functions again.')
@@ -178,35 +181,36 @@ class Uploader(object):
             if len(line) == 0:
                 continue
 
-            d = self.exchange(line)
+            resp = self.__exchange(line)
             #do some basic test of the result
-            if ('unexpected' in d) or ('stdin' in d) or len(d) > len(functions)+10:
-                log.error('error when preparing "%s"', d)
+            if ('unexpected' in resp) or ('stdin' in resp) or len(resp) > len(functions)+10:
+                log.error('error when preparing "%s"', resp)
                 return False
         return True
 
     def download_file(self, filename):
-        res = self.exchange('send("{filename}")'.format(filename=filename))
+        """Download a file from device to local filesystem"""
+        res = self.__exchange('send("{filename}")'.format(filename=filename))
         if ('unexpected' in res) or ('stdin' in res):
-            log.error('Unexpected error downloading file', res)
+            log.error('Unexpected error downloading file: %s', res)
             raise Exception('Unexpected error downloading file')
 
         #tell device we are ready to receive
-        self.write('C')
+        self.__write('C')
         #we should get a NUL terminated filename to start with
-        sent_filename = self.expect(NUL).strip()
+        sent_filename = self.__expect(NUL).strip()
         log.info('receiveing ' + sent_filename)
 
         #ACK to start download
-        self.write(ACK, True);
-        buffer = ''
+        self.__write(ACK, True)
+        buf = ''
         data = ''
-        chunk, buffer = self.read_chunk(buffer)
+        chunk, buf = self.__read_chunk(buf)
         #read chunks until we get an empty which is the end
         while chunk != '':
-            self.write(ACK,True);
+            self.__write(ACK, True)
             data = data + chunk
-            chunk, buffer = self.read_chunk(buffer)
+            chunk, buf = self.__read_chunk(buf)
         return data
 
     def read_file(self, filename, destination=''):
@@ -214,29 +218,31 @@ class Uploader(object):
             destination = filename
         log.info('Transfering %s to %s', filename, destination)
         data = self.download_file(filename)
-        with open(destination, 'w') as f:
-            f.write(data)
+        with open(destination, 'w') as fil:
+            fil.write(data)
 
     def write_file(self, path, destination='', verify='none'):
+        """sends a file to the device using the transfer protocol"""
         filename = os.path.basename(path)
         if not destination:
             destination = filename
+
         log.info('Transfering %s as %s', path, destination)
-        self.writeln("recv()")
+        self.__writeln("recv()")
 
-        res = self.expect('C> ')
+        res = self.__expect('C> ')
         if not res.endswith('C> '):
             log.error('Error waiting for esp "%s"', res)
             return
         log.debug('sending destination filename "%s"', destination)
-        self.write(destination + '\x00', True)
-        if not self.got_ack():
+        self.__write(destination + '\x00', True)
+        if not self.__got_ack():
             log.error('did not ack destination filename')
             return
 
-        f = open(path, 'rb')
-        content = f.read()
-        f.close()
+        fil = open(path, 'rb')
+        content = fil.read()
+        fil.close()
 
         log.debug('sending %d bytes in %s', len(content), filename)
         pos = 0
@@ -247,16 +253,16 @@ class Uploader(object):
                 rest = chunk_size
 
             data = content[pos:pos+rest]
-            if not self.write_chunk(data):
-                d = self.expect()
-                log.error('Bad chunk response "%s" %s', d, ':'.join(x.encode('hex') for x in d))
+            if not self.__write_chunk(data):
+                resp = self.__expect()
+                log.error('Bad chunk response "%s" %s', resp, ':'.join(x.encode('hex') for x in resp))
                 return
 
             pos += chunk_size
 
         log.debug('sending zero block')
         #zero size block
-        self.write_chunk('')
+        self.__write_chunk('')
 
         if verify == 'raw':
             log.info('Verifying...')
@@ -267,7 +273,7 @@ class Uploader(object):
                 log.info('Verification successfull. Contents are identical.')
         elif verify == 'sha1':
             #Calculate SHA1 on remote file. Extract just hash from result
-            data = self.exchange('shafile("'+destination+'")').splitlines()[1]
+            data = self.__exchange('shafile("'+destination+'")').splitlines()[1]
             log.info('Remote SHA1: %s', data)
 
             #Calculate hash of local data
@@ -283,24 +289,26 @@ class Uploader(object):
 
 
     def exec_file(self, path):
+        """execute the lines in the local file 'path'"""
         filename = os.path.basename(path)
         log.info('Execute %s', filename)
 
-        f = open(path, 'rt')
+        fil = open(path, 'r')
 
         res = '> '
-        for line in f:
+        for line in fil:
             line = line.rstrip('\r\n')
-            retlines = (res + self.exchange(line)).splitlines()
+            retlines = (res + self.__exchange(line)).splitlines()
             # Log all but the last line
             res = retlines.pop()
             for lin in retlines:
                 log.info(lin)
         # last line
         log.info(res)
-        f.close()
+        fil.close()
 
-    def got_ack(self):
+    def __got_ack(self):
+        """Returns true if ACK is received"""
         log.debug('waiting for ack')
         res = self._port.read(1)
         log.debug('ack read %s', res.encode('hex'))
@@ -311,12 +319,14 @@ class Uploader(object):
         lines = data.replace('\r', '').split('\n')
 
         for line in lines:
-            self.exchange(line)
+            self.__exchange(line)
 
         return
 
 
-    def write_chunk(self, chunk):
+    def __write_chunk(self, chunk):
+        """formats and sends a chunk of data to the device according
+        to transfer protocol"""
         log.debug('writing %d bytes chunk', len(chunk))
         data = BLOCK_START + chr(len(chunk)) + chunk
         if len(chunk) < 128:
@@ -324,87 +334,97 @@ class Uploader(object):
             log.debug('pad with %d characters', padding)
             data = data + (' ' * padding)
         log.debug("packet size %d", len(data))
-        self.write(data)
+        self.__write(data)
         self._port.flush()
-        return self.got_ack()
+        return self.__got_ack()
 
 
-    def read_chunk(self, buffer):
+    def __read_chunk(self, buf):
+        """Read a chunk of data"""
         log.debug('reading chunk')
         timeout = self._port.timeout
         if SYSTEM != 'Windows':
-            timer = self._port.timeout
             # Checking for new data every 100us is fast enough
-            lt = 0.0001
-            if self._port.timeout != lt:
-                self._port.timeout = lt
+            if self._port.timeout != MINIMAL_TIMEOUT:
+                self._port.timeout = MINIMAL_TIMEOUT
 
         end = time.time() + timeout
 
-        while len(buffer) < 130 and time.time() <= end:
-            buffer = buffer + self._port.read()
+        while len(buf) < 130 and time.time() <= end:
+            buf = buf + self._port.read()
 
-        if buffer[0] != BLOCK_START or len(buffer) < 130:
-            print 'buffer size:', len(buffer)
-            log.debug('buffer binary: ', ':'.join(x.encode('hex') for x in buffer))
+        if buf[0] != BLOCK_START or len(buf) < 130:
+            print 'buffer size:', len(buf)
+            log.debug('buffer binary: %s ', ':'.join(x.encode('hex') for x in buf))
             raise Exception('Bad blocksize or start byte')
 
-        chunk_size = ord(buffer[1])
-        data = buffer[2:chunk_size+2]
-        buffer = buffer[130:]
-        return (data, buffer)
+        if SYSTEM != 'Windows':
+            self._port.timeout = timeout
+
+        chunk_size = ord(buf[1])
+        data = buf[2:chunk_size+2]
+        buf = buf[130:]
+        return (data, buf)
 
 
     def file_list(self):
+        """list files on the device"""
         log.info('Listing files')
-        res = self.exchange(LIST_FILES)
+        res = self.__exchange(LIST_FILES)
         log.info(res)
         return res
 
-    def file_do(self, f):
-        log.info('Executing '+f)
-        res = self.exchange('dofile("'+f+'")')
+    def file_do(self, filename):
+        """Execute a file on the device using 'do'"""
+        log.info('Executing '+filename)
+        res = self.__exchange('dofile("'+filename+'")')
         log.info(res)
         return res
 
     def file_format(self):
+        """Formats device filesystem"""
         log.info('Formating, can take up to 1 minute...')
-        res = self.exchange('file.format()', timeout=60)
+        res = self.__exchange('file.format()', timeout=60)
         if 'format done' not in res:
             log.error(res)
         else:
             log.info(res)
         return res
 
-    def file_print(self, f):
-        log.info('Printing ' + f)
-        res = self.exchange(PRINT_FILE.format(filename=f))
+    def file_print(self, filename):
+        """Prints a file on the device to console"""
+        log.info('Printing ' + filename)
+        res = self.__exchange(PRINT_FILE.format(filename=filename))
         log.info(res)
         return res
 
     def node_heap(self):
+        """Show device heap size"""
         log.info('Heap')
-        res = self.exchange('print(node.heap())')
+        res = self.__exchange('print(node.heap())')
         log.info(res)
         return res
 
     def node_restart(self):
+        """Restarts device"""
         log.info('Restart')
-        res = self.exchange('node.restart()')
+        res = self.__exchange('node.restart()')
         log.info(res)
         return res
 
     def file_compile(self, path):
+        """Compiles a file specified by path on the device"""
         log.info('Compile '+path)
         cmd = 'node.compile("%s")' % path
-        res = self.exchange(cmd)
+        res = self.__exchange(cmd)
         log.info(res)
         return res
 
     def file_remove(self, path):
+        """Removes a file on the device"""
         log.info('Remove '+path)
         cmd = 'file.remove("%s")' % path
-        res = self.exchange(cmd)
+        res = self.__exchange(cmd)
         log.info(res)
         return res
 

+ 3 - 3
nodemcu_uploader/utils.py

@@ -1,15 +1,15 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+"""Various utility functions"""
 
 from platform import system
 from os import environ
 
 __all__ = ['default_port', 'system']
 
-def default_port(sysname = system()):
+def default_port(sysname=system()):
     """This returns the default port used for different systems if SERIALPORT env variable is not set"""
-    system_default =  {
+    system_default = {
         'Windows': 'COM1',
         'Darwin': '/dev/tty.SLAB_USBtoUART'
     }.get(sysname, '/dev/ttyUSB0')

+ 2 - 1
nodemcu_uploader/version.py

@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+"""just keeper of current version"""
 
-#remember to update tests when version changes
+#TODO: remember to update tests when version changes
 __version__ = '0.3.0'

+ 16 - 0
pylintrc

@@ -0,0 +1,16 @@
+[MASTER]
+persistent=yes
+
+[FORMAT]
+# Maximum number of characters on a single line.
+max-line-length=120
+
+[DESIGN]
+max-args=6
+
+[MESSAGES CONTROL]
+disable=I0011
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+include-ids=yes

+ 5 - 3
setup.py

@@ -1,11 +1,13 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
+"""Setup for nodemcu-uploader"""
+
 from setuptools import setup
 
-exec(open('nodemcu_uploader/version.py').read())
+exec(open('nodemcu_uploader/version.py').read()) #pylint: disable=W0122
 
 setup(name='nodemcu-uploader',
-      version=__version__,
+      version=__version__, #pylint: disable=E0602
       install_requires=[
           'pyserial>=2.7'
       ],
@@ -22,7 +24,7 @@ setup(name='nodemcu-uploader',
           'Programming Language :: Python :: 2.7'
       ],
       license='MIT',
-      test_suite = "tests.get_tests",
+      test_suite="tests.get_tests",
       entry_points={
           'console_scripts': [
               'nodemcu-uploader=nodemcu_uploader.main:main_func'

+ 6 - 3
tests/__init__.py

@@ -1,16 +1,19 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
 import unittest
+import logging
 
 def get_tests():
     return full_suite()
 
 def full_suite():
+    logging.basicConfig(filename='test-debug.log', level=logging.INFO, format='%(message)s')
+
     from .misc import MiscTestCase
-    #from .uploader import UploaderTestCase
+    from .uploader import UploaderTestCase
     # from .serializer import ResourceTestCase as SerializerTestCase
     # from .utils import UtilsTestCase
 
     miscsuite = unittest.TestLoader().loadTestsFromTestCase(MiscTestCase)
-    #uploadersuite = unittest.TestLoader().loadTestsFromTestCase(UploaderTestCase)
-    return unittest.TestSuite([miscsuite, ])
+    uploadersuite = unittest.TestLoader().loadTestsFromTestCase(UploaderTestCase)
+    return unittest.TestSuite([miscsuite, uploadersuite])

+ 22 - 5
tests/uploader.py

@@ -1,15 +1,32 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2015-2016 Peter Magnusson <peter@birchroad.net>
 import unittest
+import os, time
 from nodemcu_uploader import Uploader, __version__
 
+LOOPPORT='loop://'
+
 #on which port should the tests be performed
-PORT = 'loop://'
+SERIALPORT = os.environ.get('SERIALPORT', LOOPPORT)
 
-#which speed should the tests use
-BAUD = 115200
 
 class UploaderTestCase(unittest.TestCase):
+    uploader = None
+    def setUp(self):
+        self.uploader =  Uploader(SERIALPORT)
+
+    def tearDown(self):
+        self.uploader.node_restart()
+        self.uploader.close()
+        time.sleep(1)
+
+    # def test_initialize(self):
+    #     print SERIALPORT
+
+
+
+    @unittest.skipUnless(SERIALPORT <>  LOOPPORT, 'Needs a configured SERIALPORT')
+    def test_upload_and_verify_raw(self):
+        self.uploader.prepare()
+        self.uploader.write_file('tests/fixtures/big_file.txt', verify='raw')
 
-    def test_initialize(self):
-        uploader = Uploader(PORT, BAUD)

+ 2 - 2
tests/winserial.py

@@ -9,7 +9,7 @@ import time
 SERIALPORT = os.environ.get('SERIALPORT', default_port())
 
 def expect(port, timeout, exp='> '):
-    timer = port.timeout
+    timeout = port.timeout
     # lt = 0.0001
     # if port.timeout != lt:
     #     port.timeout = lt
@@ -19,7 +19,7 @@ def expect(port, timeout, exp='> '):
     while not data.endswith(exp) and time.time() <= end:
         data += port.read()
 
-    # port.timeout = timer
+    # port.timeout = timeout
 
     return data
 

Some files were not shown because too many files changed in this diff