def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double=self) return self
def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double = self) return self
def onClickDoItButton(self): """ Called when the 'DoIt' button is pressed. Reads the entered URL, validates it and initiates the trace route command :return: None """ try: self.statusbar.clearMessage() self.statusbar.showMessage("Working...") self.doLookupPushButton.setEnabled(False) self.textOutput.clear() # read entered URL url = self.urlLineEdit.text() if url: with open("./busy.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) self.traceRouteThreadedHandler = TraceRoute(url) # set up callbacks for the trace route output self.traceRouteThreadedHandler.traceRouteTerminated.connect( self.onTraceRouteComplete) self.traceRouteThreadedHandler.textOutputReady.connect( self.onTraceRouteRawOutput) self.traceRouteThreadedHandler.start() else: self.statusbar.showMessage("URL is invalid", 5000) self.doLookupPushButton.setEnabled(True) QMessageBox.information(self, "Empty Field", "The entered URL is invalid") except Exception as e: QMessageBox.critical(self, "Critical", "Problem initiating trace route : " + str(e))
def onClickDoItButton(self): """ Called when the 'DoIt' button is pressed. Reads the entered URL, validates it and initiates the trace route command :return: None """ try: self.statusbar.clearMessage() self.statusbar.showMessage("Working...") self.doLookupPushButton.setEnabled(False) self.textOutput.clear() # read entered URL url = self.urlLineEdit.text() if url: with open("./busy.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) self.traceRouteThreadedHandler = TraceRoute(url) # set up callbacks for the trace route output self.traceRouteThreadedHandler.traceRouteTerminated.connect(self.onTraceRouteComplete) self.traceRouteThreadedHandler.textOutputReady.connect(self.onTraceRouteRawOutput) self.traceRouteThreadedHandler.start() else: self.statusbar.showMessage("URL is invalid", 5000) self.doLookupPushButton.setEnabled(True) QMessageBox.information(self, "Empty Field", "The entered URL is invalid") except Exception as e: QMessageBox.critical(self, "Critical", "Problem initiating trace route : " + str(e))
class Mock(_TestDouble): """Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. """ __expectation__ =[]#[MockedCall(attribute, args, kargs),] __recording__ = RECORDING __traceroute__ = None __traceroute_expected__ = None __dependency_injection__ = None def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double = self) return self def __methodCalled__(self, *args, **kargs): property = getframeinfo(getframe(1))[2] return self._property_called(property, args, kargs) def _property_called(self, property, args=[], kargs={}): if self.__recording__: self.__traceroute_expected__.remember() self._new_expectation(MockedCall(property, args = args, kargs = kargs, response = self)) return self else: self.__traceroute__.remember() return self._expectancy_recorded(property, args, kargs) def __exit__(self, type, value, traceback): self.__dependency_injection__.restoure_import() self.__recording__ = STOPRECORD def __setattr__(self, attr, value): if attr in dir(Mock): object.__setattr__(self, attr, value) else: self._property_called('__setattr__', args=[attr, value]) def _new_expectation(self, attr): self.__expectation__.append(attr) def __rshift__(self, response): self.__expectation__[-1].set_response(response) __lshift__ = __rshift__ def _expectancy_recorded(self, attr, args=[], kargs={}): try: if self._is_ordered(): return self._call_mocked_ordered(attr, args, kargs) else: return self._call_mocked_unordered(attr, args, kargs) except (CallExpectation, IndexError): raise MockExpectationError(self._unexpected_call_msg(attr, args, kargs)) def _unexpected_call_msg(self, attr, args, kargs): return ("Mock Object received unexpected call:%s\n" "Expected:\n" "%s\n" "Got:\n" "%s") % ( format_called(attr, args, kargs), self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_trace()) def _is_ordered(self): return self.__kargs__.get('ordered', True) def _call_mocked_unordered(self, attr, args, kargs): for number, call in enumerate(self.__expectation__): if call.has_callable(attr, args, kargs): call_mocked = self.__expectation__.pop(number) return call_mocked.call(attr, args, kargs) raise CallExpectation("Mock object has no called %s" %attr) def _call_mocked_ordered(self, attr, args, kargs): call_mocked = self.__expectation__.pop(0) return call_mocked.call(attr, args, kargs) def __getattr__(self, x): return self._property_called('__getattribute__',[x]) def validate(self): self.__dependency_injection__.restoure_object() if self.__expectation__: raise MockExpectationError( self._call_waiting_msg()) def __del__(self): self.__dependency_injection__.restoure_object() if self.__expectation__: print self._call_waiting_msg() def _call_waiting_msg(self): return("Call waiting:\n" "Expected:\n" "%s\n" "Got only:\n" "%s") % ( self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_code())
class Mock(_TestDouble): """Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive. """ __expectation__ = [] #[MockedCall(attribute, args, kargs),] __recording__ = RECORDING __traceroute__ = None __traceroute_expected__ = None __dependency_injection__ = None def __enter__(self): self.__traceroute__ = TraceRoute() self.__traceroute_expected__ = TraceRoute() self.__expectation__ = [] self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double=self) return self def __methodCalled__(self, *args, **kargs): property = getframeinfo(getframe(1))[2] return self._property_called(property, args, kargs) def _property_called(self, property, args=[], kargs={}): if self.__recording__: self.__traceroute_expected__.remember() self._new_expectation( MockedCall(property, args=args, kargs=kargs, response=self)) return self else: self.__traceroute__.remember() return self._expectancy_recorded(property, args, kargs) def __exit__(self, type, value, traceback): self.__dependency_injection__.restore_import() self.__recording__ = STOPRECORD def __setattr__(self, attr, value): if attr in dir(Mock): object.__setattr__(self, attr, value) else: self._property_called('__setattr__', args=[attr, value]) def _new_expectation(self, attr): self.__expectation__.append(attr) def __rshift__(self, response): self.__expectation__[-1].set_response(response) __lshift__ = __rshift__ def _expectancy_recorded(self, attr, args=[], kargs={}): try: if self._is_ordered(): return self._call_mocked_ordered(attr, args, kargs) else: return self._call_mocked_unordered(attr, args, kargs) except (CallExpectation, IndexError): raise MockExpectationError( self._unexpected_call_msg(attr, args, kargs)) def _unexpected_call_msg(self, attr, args, kargs): return ("Mock Object received unexpected call:%s\n" "Expected:\n" "%s\n" "Got:\n" "%s") % (format_called(attr, args, kargs), self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_trace()) def _is_ordered(self): return self.__kargs__.get('ordered', True) def _call_mocked_unordered(self, attr, args, kargs): for number, call in enumerate(self.__expectation__): if call.has_callable(attr, args, kargs): call_mocked = self.__expectation__.pop(number) return call_mocked.call(attr, args, kargs) raise CallExpectation("Mock object has no called %s" % attr) def _call_mocked_ordered(self, attr, args, kargs): call_mocked = self.__expectation__.pop(0) return call_mocked.call(attr, args, kargs) def __getattr__(self, x): return self._property_called('__getattribute__', [x]) def validate(self): self.__dependency_injection__.restore_object() if self.__expectation__: raise MockExpectationError(self._call_waiting_msg()) def __del__(self): self.__dependency_injection__.restore_object() if self.__expectation__: print self._call_waiting_msg() def _call_waiting_msg(self): return ("Call waiting:\n" "Expected:\n" "%s\n" "Got only:\n" "%s") % (self.__traceroute_expected__.stack_code(), self.__traceroute__.stack_code())
class Stub(_TestDouble): """Stubs provides canned answers to calls made during the test. """ __expectation__= [] # [(attribute, args, kargs),] __recording__ = RECORDING __last_property_called__ = None __dependency_injection__ = None __traceroute__ = None def __enter__(self): self.__expectation__= [] self.__traceroute__ = TraceRoute() self.__recording__ = RECORDING self.__dependency_injection__ = DependencyInjection(double = self) return self def __methodCalled__(self, *args, **kargs): property_name = self._property_called_name() return self._property_called(property_name, args, kargs) def _property_called_name(self): property_called_name = self.__last_property_called__ or getframeinfo(getframe(2))[2] self.__last_property_called__ = None return property_called_name def _property_called(self, property, args=[], kargs={}, response=None): if self.__recording__: response = response if response is not None else self self._new_expectation([property, args, kargs, response]) return self else: self.__traceroute__.remember() return self._expectation_value(property, args, kargs) def __exit__(self, type, value, traceback): self.__dependency_injection__.restore_import() self.__recording__ = STOPRECORD def __setattr__(self, attr, value): if attr in dir(Stub): object.__setattr__(self, attr, value) else: self._property_called('__setattr__', args=[attr, value]) def _new_expectation(self, expectation): self.__expectation__.append(expectation) def __rshift__(self, response): self.__expectation__[-1][3] = response __lshift__ = __rshift__ def _expectation_value(self, attr, args=[], kargs={}): for position, (attr_expectation, args_expectation, kargs_expectation, response) in enumerate(self.__expectation__): if (attr_expectation, args_expectation, kargs_expectation) == (attr, args, kargs): self._to_the_end(position) return response if self._has_proxy(): return self._proxy(attr, args, kargs) self._attribute_expectation(attr, args, kargs) def _attribute_expectation(self, attr, args, kargs): raise AttributeError( "Stub Object received unexpected call. %s\n%s"%( self._format_called(attr, args, kargs), self.__traceroute__.stack_trace())) def _proxy(self, attr, args, kargs): return getattr(self.__kargs__.get('proxy'), attr)(*args, **kargs) def _has_proxy(self): return self.__kargs__.has_key('proxy') def _format_called(self, attr, args, kargs): if attr == '__call__' and self.__last_property_called__: attr = self.__last_property_called__ return format_called(attr, args, kargs) def _to_the_end(self, position): self.__expectation__.append(self.__expectation__.pop(position)) def __getattr__(self, x): self.__last_property_called__ = x return self._property_called('__getattribute__', (x,), response=self) def __del__(self): self.__dependency_injection__.restore_object() def restore_import(self): self.__dependency_injection__.restore_object()
class VisualTraceRoute(QMainWindow, visual_traceroute_ui.Ui_visual_traceroute_main_window): """ Performs a trace route on a given IP address, and displays as a raw text output and an overlay on top of Google Maps. This makes use of http://ip-api.com to determine the latitude and longitude (among other attributes) of each IP address in the route. """ def __init__(self): """ Sets up the initial windows """ super(VisualTraceRoute, self).__init__() self.setupUi(self) self.statusbar.show() self.setWindowTitle("Visual TraceRoute") self.setWindowIcon(QIcon('network-icon.png')) self.routeListObjectWrapper = RouteWrapper() # set up buttons self.doLookupPushButton.setToolTip("start Trace Route") self.doLookupPushButton.clicked.connect(self.onClickDoItButton) self.doLookupPushButton.setAutoDefault(True) # set up menu handlers self.aboutMenuItem.triggered.connect(self.onAboutClicked) self.exitMenuItem.triggered.connect(self.close) # set up async worker thread self.traceRouteThreadedHandler = None # set up web view hbx = QHBoxLayout() self.map.setLayout(hbx) self.web = QWebView() self.web.page().mainFrame().javaScriptWindowObjectCleared.connect(self.addJavascriptObjects) self.web.page().mainFrame().addToJavaScriptWindowObject("route_list", self.routeListObjectWrapper) hbx.addWidget(self.web) self.web.show() @pyqtSlot() def addJavascriptObjects(self): """ Needed to repopulate the Javascript with the python objects each time the web page is refreshed :return: None """ self.web.page().mainFrame().addToJavaScriptWindowObject("route_list", self.routeListObjectWrapper) @pyqtSlot() def onClickDoItButton(self): """ Called when the 'DoIt' button is pressed. Reads the entered URL, validates it and initiates the trace route command :return: None """ try: self.statusbar.clearMessage() self.statusbar.showMessage("Working...") self.doLookupPushButton.setEnabled(False) self.textOutput.clear() # read entered URL url = self.urlLineEdit.text() if url: with open("./busy.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) self.traceRouteThreadedHandler = TraceRoute(url) # set up callbacks for the trace route output self.traceRouteThreadedHandler.traceRouteTerminated.connect(self.onTraceRouteComplete) self.traceRouteThreadedHandler.textOutputReady.connect(self.onTraceRouteRawOutput) self.traceRouteThreadedHandler.start() else: self.statusbar.showMessage("URL is invalid", 5000) self.doLookupPushButton.setEnabled(True) QMessageBox.information(self, "Empty Field", "The entered URL is invalid") except Exception as e: QMessageBox.critical(self, "Critical", "Problem initiating trace route : " + str(e)) @pyqtSlot(str) def onTraceRouteRawOutput(self, command_output): """ Accepts a single line of text from the traceroute command, and displays on the text view :param command_output: a single line from the traceroute output :return: None """ try: self.textOutput.moveCursor(QTextCursor.End) self.textOutput.insertPlainText(command_output) except Exception as e: QMessageBox.critical(self, "Critical", "Problem updating UI with traceroute text output : " + str(e)) @pyqtSlot(object) def onTraceRouteComplete(self, route_list): """ Called when the trace route command is complete. Takes the entire route list, passes it to the Javascript and draws the visual trace route :param route_list: a list of IP addresses :return: None """ try: self.doLookupPushButton.setEnabled(True) self.doLookupPushButton.update() self.statusbar.clearMessage() self.statusbar.showMessage("Complete!") self.routeListObjectWrapper.clear() self.routeListObjectWrapper.add(route_list) self.web.page().mainFrame().addToJavaScriptWindowObject("route_list", self.routeListObjectWrapper) with open("./map_js.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) except Exception as e: QMessageBox.critical(self, "Critical", "Problem performing TraceRoute command : " + str(e)) @pyqtSlot() def onAboutClicked(self): box = QMessageBox.information(self, "About Visual TraceRoute", "Visual trace route") def closeEvent(self, event): """ Intercepts the app exit event :param event: incoming close event :return: None """ quit_msg = "Are you sure you want to exit the program?" reply = QMessageBox.question(self, 'Message', quit_msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()
class VisualTraceRoute(QMainWindow, visual_traceroute_ui.Ui_visual_traceroute_main_window): """ Performs a trace route on a given IP address, and displays as a raw text output and an overlay on top of Google Maps. This makes use of http://ip-api.com to determine the latitude and longitude (among other attributes) of each IP address in the route. """ def __init__(self): """ Sets up the initial windows """ super(VisualTraceRoute, self).__init__() self.setupUi(self) self.statusbar.show() self.setWindowTitle("Visual TraceRoute") self.setWindowIcon(QIcon('network-icon.png')) self.routeListObjectWrapper = RouteWrapper() # set up buttons self.doLookupPushButton.setToolTip("start Trace Route") self.doLookupPushButton.clicked.connect(self.onClickDoItButton) self.doLookupPushButton.setAutoDefault(True) # set up menu handlers self.aboutMenuItem.triggered.connect(self.onAboutClicked) self.exitMenuItem.triggered.connect(self.close) # set up async worker thread self.traceRouteThreadedHandler = None # set up web view hbx = QHBoxLayout() self.map.setLayout(hbx) self.web = QWebView() self.web.page().mainFrame().javaScriptWindowObjectCleared.connect( self.addJavascriptObjects) self.web.page().mainFrame().addToJavaScriptWindowObject( "route_list", self.routeListObjectWrapper) hbx.addWidget(self.web) self.web.show() @pyqtSlot() def addJavascriptObjects(self): """ Needed to repopulate the Javascript with the python objects each time the web page is refreshed :return: None """ self.web.page().mainFrame().addToJavaScriptWindowObject( "route_list", self.routeListObjectWrapper) @pyqtSlot() def onClickDoItButton(self): """ Called when the 'DoIt' button is pressed. Reads the entered URL, validates it and initiates the trace route command :return: None """ try: self.statusbar.clearMessage() self.statusbar.showMessage("Working...") self.doLookupPushButton.setEnabled(False) self.textOutput.clear() # read entered URL url = self.urlLineEdit.text() if url: with open("./busy.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) self.traceRouteThreadedHandler = TraceRoute(url) # set up callbacks for the trace route output self.traceRouteThreadedHandler.traceRouteTerminated.connect( self.onTraceRouteComplete) self.traceRouteThreadedHandler.textOutputReady.connect( self.onTraceRouteRawOutput) self.traceRouteThreadedHandler.start() else: self.statusbar.showMessage("URL is invalid", 5000) self.doLookupPushButton.setEnabled(True) QMessageBox.information(self, "Empty Field", "The entered URL is invalid") except Exception as e: QMessageBox.critical(self, "Critical", "Problem initiating trace route : " + str(e)) @pyqtSlot(str) def onTraceRouteRawOutput(self, command_output): """ Accepts a single line of text from the traceroute command, and displays on the text view :param command_output: a single line from the traceroute output :return: None """ try: self.textOutput.moveCursor(QTextCursor.End) self.textOutput.insertPlainText(command_output) except Exception as e: QMessageBox.critical( self, "Critical", "Problem updating UI with traceroute text output : " + str(e)) @pyqtSlot(object) def onTraceRouteComplete(self, route_list): """ Called when the trace route command is complete. Takes the entire route list, passes it to the Javascript and draws the visual trace route :param route_list: a list of IP addresses :return: None """ try: self.doLookupPushButton.setEnabled(True) self.doLookupPushButton.update() self.statusbar.clearMessage() self.statusbar.showMessage("Complete!") self.routeListObjectWrapper.clear() self.routeListObjectWrapper.add(route_list) self.web.page().mainFrame().addToJavaScriptWindowObject( "route_list", self.routeListObjectWrapper) with open("./map_js.html", "r") as htmlFile: html = htmlFile.read() self.web.setHtml(html) except Exception as e: QMessageBox.critical( self, "Critical", "Problem performing TraceRoute command : " + str(e)) @pyqtSlot() def onAboutClicked(self): box = QMessageBox.information(self, "About Visual TraceRoute", "Visual trace route") def closeEvent(self, event): """ Intercepts the app exit event :param event: incoming close event :return: None """ quit_msg = "Are you sure you want to exit the program?" reply = QMessageBox.question(self, 'Message', quit_msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()