# Path: mcm/librouteros/api.py
# class Api:
# 
# 
#     def __init__( self, rwo ):
#         self.rwo = rwo
# 
# 
#     def run( self, cmd, args = dict() ):
#         '''
#         Run any 'non interactive' command. Returns parsed response.
# 
#         cmd Command word eg. /ip/address/print.
#         args Dictionary with key, value pairs.
#         '''
# 
#         snt = (cmd,) + mksnt( args )
#         self.rwo.writeSnt( snt )
#         response = self._readResponse()
#         trapCheck( response )
#         raiseIfFatal( response )
# 
#         return parsresp( response )
# 
# 
#     def _readResponse( self ):
#         '''
#         Read whole response.
# 
#         returns Read sentences as tuple.
#         '''
# 
#         snts = []
# 
#         while True:
# 
#             snt = self.rwo.readSnt()
#             snts.append( snt )
# 
#             if '!done' in snt:
#                 break
# 
#         return tuple( snts )
# 
# 
#     def close( self ):
#         '''
#         Send /quit and close the connection.
#         '''
# 
#         try:
#             self.rwo.writeSnt( ('/quit',) )
#             self.rwo.readSnt()
#         except LibError:
#             pass
#         finally:
#             self.rwo.close()
# 
# 
#     def __del__( self ):
#         '''
#         On garbage collection run close().
#         '''
#         self.close()
# 
# Path: mcm/librouteros/exceptions.py
# class CmdError( LibError ):
#     '''
#     Commend execution errors.
#     '''
# 
# class ConnError( LibError ):
#     '''
#     Connection related errors.
#     '''
# 
# class LibError( Exception ):
#     '''
#     This is a base exception for all other.
#     '''
# 
# Path: mcm/librouteros/connections.py
# class ReaderWriter:
# 
# 
#     def __init__( self, sock, log ):
#         self.sock = sock
#         self.log = log
# 
# 
#     def writeSnt( self, snt ):
#         '''
#         Write sentence to connection.
# 
#         sentence: Iterable (tuple or list) with words.
#         '''
# 
#         encoded = encsnt( snt )
#         self.writeSock( encoded )
#         log_snt( self.log, snt, 'write' )
# 
# 
#     def readSnt( self ):
#         '''
#         Read sentence from connection.
# 
#         returns: Sentence as tuple with words in it.
#         '''
# 
#         snt = []
#         for length in iter( self.getLen, 0 ):
#             word = self.readSock( length )
#             snt.append( word )
# 
#         decoded = decsnt( snt )
#         log_snt( self.log, decoded, 'read' )
# 
#         return decoded
# 
# 
#     def readSock( self, length ):
#         '''
#         Read as many bytes from socket as specified in length.
#         Loop as long as every byte is read unless exception is raised.
#         '''
# 
#         data = bytearray()
# 
#         try:
#             while length:
#                 read = self.sock.recv(length)
#                 if not read:
#                     raise ConnError( 'Connection unexpectedly closed. Read {read}/{total} bytes.'
#                                     .format(read = len(data), total = (len(data) + length)))
#                 data += read
#                 length -= len(read)
# 
#         except SOCKET_TIMEOUT:
#             raise ConnError( 'Socket timed out. Read {read}/{total} bytes.'
#                             .format(read = len(data), total = (len(data) + length)))
#         except SOCKET_ERROR as estr:
#             raise ConnError( 'Failed to read from socket. {reason}'.format(reason = estr))
# 
#         return data
# 
# 
#     def writeSock( self, string ):
#         '''
#         Write given string to socket. Loop as long as every byte in
#         string is written unless exception is raised.
#         '''
# 
#         try:
#             self.sock.sendall(string)
#         except SOCKET_TIMEOUT as error:
#             raise ConnError('Socket timed out. ' + str(error))
#         except SOCKET_ERROR as error:
#             raise ConnError('Failed to write to socket. ' + str(error))
# 
# 
#     def getLen( self ):
#         '''
#         Read encoded length and return it as integer.
#         '''
# 
#         first_byte = self.readSock( 1 )
#         first_byte_int = unpack( 'B', first_byte )[0]
# 
#         if first_byte_int < 128:
#             bytes_to_read = 0
#         elif first_byte_int < 192:
#             bytes_to_read = 1
#         elif first_byte_int < 224:
#             bytes_to_read = 2
#         elif first_byte_int < 240:
#             bytes_to_read = 3
#         else:
#             raise ConnError( 'unknown controll byte received {0!r}'
#                             .format( first_byte ) )
# 
#         additional_bytes = self.readSock( bytes_to_read )
# 
#         return declen( first_byte + additional_bytes )
# 
# 
#     def close( self ):
# 
#         # do not do anything if socket is already closed
#         if self.sock._closed:
#             return
#         # shutdown socket
#         try:
#             self.sock.shutdown( SHUT_RDWR )
#         except SOCKET_ERROR:
#             pass
#         finally:
#             self.sock.close()


import unittest
from mock import MagicMock, patch
from mcm.librouteros.api import Api
from mcm.librouteros.exceptions import CmdError, ConnError, LibError
from mcm.librouteros.connections import ReaderWriter
# -*- coding: UTF-8 -*-





@patch( 'mcm.librouteros.api.parsresp' )
@patch( 'mcm.librouteros.api.mksnt' )
@patch( 'mcm.librouteros.api.trapCheck' )
@patch( 'mcm.librouteros.api.raiseIfFatal' )
@patch.object( Api, '_readResponse' )

# Path: mcm/librouteros/api.py
# class Api:
# 
# 
#     def __init__( self, rwo ):
#         self.rwo = rwo
# 
# 
#     def run( self, cmd, args = dict() ):
#         '''
#         Run any 'non interactive' command. Returns parsed response.
# 
#         cmd Command word eg. /ip/address/print.
#         args Dictionary with key, value pairs.
#         '''
# 
#         snt = (cmd,) + mksnt( args )
#         self.rwo.writeSnt( snt )
#         response = self._readResponse()
#         trapCheck( response )
#         raiseIfFatal( response )
# 
#         return parsresp( response )
# 
# 
#     def _readResponse( self ):
#         '''
#         Read whole response.
# 
#         returns Read sentences as tuple.
#         '''
# 
#         snts = []
# 
#         while True:
# 
#             snt = self.rwo.readSnt()
#             snts.append( snt )
# 
#             if '!done' in snt:
#                 break
# 
#         return tuple( snts )
# 
# 
#     def close( self ):
#         '''
#         Send /quit and close the connection.
#         '''
# 
#         try:
#             self.rwo.writeSnt( ('/quit',) )
#             self.rwo.readSnt()
#         except LibError:
#             pass
#         finally:
#             self.rwo.close()
# 
# 
#     def __del__( self ):
#         '''
#         On garbage collection run close().
#         '''
#         self.close()
# 
# Path: mcm/librouteros/exceptions.py
# class CmdError( LibError ):
#     '''
#     Commend execution errors.
#     '''
# 
# class ConnError( LibError ):
#     '''
#     Connection related errors.
#     '''
# 
# class LibError( Exception ):
#     '''
#     This is a base exception for all other.
#     '''
# 
# Path: mcm/librouteros/connections.py
# class ReaderWriter:
# 
# 
#     def __init__( self, sock, log ):
#         self.sock = sock
#         self.log = log
# 
# 
#     def writeSnt( self, snt ):
#         '''
#         Write sentence to connection.
# 
#         sentence: Iterable (tuple or list) with words.
#         '''
# 
#         encoded = encsnt( snt )
#         self.writeSock( encoded )
#         log_snt( self.log, snt, 'write' )
# 
# 
#     def readSnt( self ):
#         '''
#         Read sentence from connection.
# 
#         returns: Sentence as tuple with words in it.
#         '''
# 
#         snt = []
#         for length in iter( self.getLen, 0 ):
#             word = self.readSock( length )
#             snt.append( word )
# 
#         decoded = decsnt( snt )
#         log_snt( self.log, decoded, 'read' )
# 
#         return decoded
# 
# 
#     def readSock( self, length ):
#         '''
#         Read as many bytes from socket as specified in length.
#         Loop as long as every byte is read unless exception is raised.
#         '''
# 
#         data = bytearray()
# 
#         try:
#             while length:
#                 read = self.sock.recv(length)
#                 if not read:
#                     raise ConnError( 'Connection unexpectedly closed. Read {read}/{total} bytes.'
#                                     .format(read = len(data), total = (len(data) + length)))
#                 data += read
#                 length -= len(read)
# 
#         except SOCKET_TIMEOUT:
#             raise ConnError( 'Socket timed out. Read {read}/{total} bytes.'
#                             .format(read = len(data), total = (len(data) + length)))
#         except SOCKET_ERROR as estr:
#             raise ConnError( 'Failed to read from socket. {reason}'.format(reason = estr))
# 
#         return data
# 
# 
#     def writeSock( self, string ):
#         '''
#         Write given string to socket. Loop as long as every byte in
#         string is written unless exception is raised.
#         '''
# 
#         try:
#             self.sock.sendall(string)
#         except SOCKET_TIMEOUT as error:
#             raise ConnError('Socket timed out. ' + str(error))
#         except SOCKET_ERROR as error:
#             raise ConnError('Failed to write to socket. ' + str(error))
# 
# 
#     def getLen( self ):
#         '''
#         Read encoded length and return it as integer.
#         '''
# 
#         first_byte = self.readSock( 1 )
#         first_byte_int = unpack( 'B', first_byte )[0]
# 
#         if first_byte_int < 128:
#             bytes_to_read = 0
#         elif first_byte_int < 192:
#             bytes_to_read = 1
#         elif first_byte_int < 224:
#             bytes_to_read = 2
#         elif first_byte_int < 240:
#             bytes_to_read = 3
#         else:
#             raise ConnError( 'unknown controll byte received {0!r}'
#                             .format( first_byte ) )
# 
#         additional_bytes = self.readSock( bytes_to_read )
# 
#         return declen( first_byte + additional_bytes )
# 
# 
#     def close( self ):
# 
#         # do not do anything if socket is already closed
#         if self.sock._closed:
#             return
#         # shutdown socket
#         try:
#             self.sock.shutdown( SHUT_RDWR )
#         except SOCKET_ERROR:
#             pass
#         finally:
#             self.sock.close()


# Path: tests/test_api.py
import unittest
from mock import MagicMock, patch
from mcm.librouteros.api import Api
from mcm.librouteros.exceptions import CmdError, ConnError, LibError
from mcm.librouteros.connections import ReaderWriter

# -*- coding: UTF-8 -*-





@patch( 'mcm.librouteros.api.parsresp' )
@patch( 'mcm.librouteros.api.mksnt' )
@patch( 'mcm.librouteros.api.trapCheck' )
@patch( 'mcm.librouteros.api.raiseIfFatal' )
@patch.object( Api, '_readResponse' )

@patch.object( Api, 'close' )