def _is_error_logline(self, msg): """Check if the given LogLine is some kind of error message.""" is_js_error = (msg.category == 'js' and testutils.pattern_match(pattern='[*] [FAIL] *', value=msg.message)) # Try to complain about the most common mistake when accidentally # loading external resources. is_ddg_load = testutils.pattern_match( pattern="load status for <* tab_id=* url='*duckduckgo*'>: *", value=msg.message) is_log_error = (msg.loglevel > logging.INFO and not msg.message.startswith("Ignoring world ID") and not msg.message.startswith( "Could not initialize QtNetwork SSL support.")) return is_log_error or is_js_error or is_ddg_load
def _match_data(self, value, expected): """Helper for wait_for to match a given value. The behavior of this method is slightly different depending on the types of the filtered values: - If expected is None, the filter always matches. - If the value is a string or bytes object and the expected value is too, the pattern is treated as a glob pattern (with only * active). - If the value is a string or bytes object and the expected value is a compiled regex, it is used for matching. - If the value is any other type, == is used. Return: A bool """ regex_type = type(re.compile('')) if expected is None: return True elif isinstance(expected, regex_type): return expected.search(value) elif isinstance(value, (bytes, str)): return testutils.pattern_match(pattern=expected, value=value) else: return value == expected
def _check_marks(quteproc, quickmarks, expected, contains): """Make sure the given line does (not) exist in the bookmarks. Args: quickmarks: True to check the quickmarks file instead of bookmarks. expected: The line to search for. contains: True if the line should be there, False otherwise. """ if quickmarks: mark_file = os.path.join(quteproc.basedir, 'config', 'quickmarks') else: mark_file = os.path.join(quteproc.basedir, 'config', 'bookmarks', 'urls') quteproc.clear_data() # So we don't match old messages quteproc.send_cmd(':save') quteproc.wait_for(message='Saved to {}'.format(mark_file)) with open(mark_file, 'r', encoding='utf-8') as f: lines = f.readlines() matched_line = any( testutils.pattern_match(pattern=expected, value=line.rstrip('\n')) for line in lines) assert matched_line == contains, lines
def _maybe_skip(self): """Skip the test if [SKIP] lines were logged.""" skip_texts = [] for msg in self._data: if (msg.category == 'js' and testutils.pattern_match(pattern='[*] [SKIP] *', value=msg.message)): skip_texts.append(msg.message.partition(' [SKIP] ')[2]) if skip_texts: pytest.skip(', '.join(skip_texts))
def check_header(quteproc, header, value): """Check if a given header is set correctly. This assumes we're on the server header page. """ content = quteproc.get_content() data = json.loads(content) print(data) if value == '<unset>': assert header not in data['headers'] elif value.startswith("'") and value.endswith("'"): # literal match actual = data['headers'][header] assert actual == value[1:-1] else: actual = data['headers'][header] assert testutils.pattern_match(pattern=value, value=actual)
def _process_line(self, log_line): """Check if the line matches any initial lines we're interested in.""" start_okay_message = ( "load status for <qutebrowser.browser.* tab_id=0 " "url='about:blank'>: LoadStatus.success") if (log_line.category == 'ipc' and log_line.message.startswith("Listening as ")): self._ipc_socket = log_line.message.split(' ', maxsplit=2)[2] elif (log_line.category == 'webview' and testutils.pattern_match(pattern=start_okay_message, value=log_line.message)): log_line.waited_for = True self.ready.emit() elif (log_line.category == 'init' and log_line.module == 'standarddir' and log_line.function == 'init' and log_line.message.startswith('Base directory:')): self.basedir = log_line.message.split(':', maxsplit=1)[1].strip() elif self._is_error_logline(log_line): self.got_error.emit()
def is_ignored_lowlevel_message(message): """Check if we want to ignore a lowlevel process output.""" ignored_messages = [ # https://travis-ci.org/qutebrowser/qutebrowser/jobs/157941720 # ??? 'Xlib: sequence lost*', # Started appearing with Qt 5.8... # https://patchwork.sourceware.org/patch/10255/ ("*_dl_allocate_tls_init: Assertion `listp->slotinfo[cnt].gen <= " "GL(dl_tls_generation)' failed!*"), # ??? 'getrlimit(RLIMIT_NOFILE) failed', 'libpng warning: Skipped (ignored) a chunk between APNG chunks', # Travis CI containers don't have a /etc/machine-id ('*D-Bus library appears to be incorrectly set up; failed to read ' 'machine uuid: Failed to open "/etc/machine-id": No such file or ' 'directory'), 'See the manual page for dbus-uuidgen to correct this issue.', # Travis CI macOS: # 2017-09-11 07:32:56.191 QtWebEngineProcess[5455:28501] Couldn't set # selectedTextBackgroundColor from default () "* Couldn't set selectedTextBackgroundColor from default ()", # Mac Mini: # <<<< VTVideoEncoderSelection >>>> # VTSelectAndCreateVideoEncoderInstanceInternal: no video encoder # found for 'avc1' # # [22:32:03.636] VTSelectAndCreateVideoEncoderInstanceInternal # signalled err=-12908 (err) (Video encoder not available) at # /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/ # VideoToolbox/VTVideoEncoderSelection.c line 1245 # # [22:32:03.636] VTCompressionSessionCreate signalled err=-12908 (err) # (Could not select and open encoder instance) at # /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/ # VideoToolbox/VTCompressionSession.c # line 946 '*VTSelectAndCreateVideoEncoderInstanceInternal*', '*VTSelectAndCreateVideoEncoderInstanceInternal*', '*VTCompressionSessionCreate*', # During shutdown on AppVeyor: # https://ci.appveyor.com/project/qutebrowser/qutebrowser/build/master-2089/job/or4tbct1oeqsfhfm 'QNetworkProxyFactory: factory 0x* has returned an empty result set', # Qt 5.10 with debug Chromium # [1016/155149.941048:WARNING:stack_trace_posix.cc(625)] Failed to open # file: /home/florian/#14687139 (deleted) # Error: No such file or directory ' Error: No such file or directory', # Qt 5.7.1 'qt.network.ssl: QSslSocket: cannot call unresolved function *', # Qt 5.11 # DevTools listening on ws://127.0.0.1:37945/devtools/browser/... 'DevTools listening on *', # /home/travis/build/qutebrowser/qutebrowser/.tox/py36-pyqt511-cov/lib/ # python3.6/site-packages/PyQt5/Qt/libexec/QtWebEngineProcess: # /lib/x86_64-linux-gnu/libdbus-1.so.3: no version information # available (required by /home/travis/build/qutebrowser/qutebrowser/ # .tox/py36-pyqt511-cov/lib/python3.6/site-packages/PyQt5/Qt/libexec/ # ../lib/libQt5WebEngineCore.so.5) '*/QtWebEngineProcess: /lib/x86_64-linux-gnu/libdbus-1.so.3: no ' 'version information available (required by ' '*/libQt5WebEngineCore.so.5)', # hunter and Python 3.9 # https://github.com/ionelmc/python-hunter/issues/87 '<frozen importlib._bootstrap>:*: RuntimeWarning: builtins.type size changed, ' 'may indicate binary incompatibility. Expected 872 from C header, got 880 from ' 'PyObject', ] return any( testutils.pattern_match(pattern=pattern, value=message) for pattern in ignored_messages)
def is_ignored_chromium_message(line): msg_re = re.compile( r""" \[ (\d+:\d+:)? # Process/Thread ID \d{4}/[\d.]+: # MMDD/Time (?P<loglevel>[A-Z]+): # Log level [^ :]+ # filename / line \] \ (?P<message>.*) # message """, re.VERBOSE) match = msg_re.fullmatch(line) if match is None: return False if match.group('loglevel') == 'INFO': return True message = match.group('message') ignored_messages = [ # [27289:27289:0605/195958.776146:INFO:zygote_host_impl_linux.cc(107)] # No usable sandbox! Update your kernel or see # https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md # for more information on developing with the SUID sandbox. If you want # to live dangerously and need an immediate workaround, you can try # using --no-sandbox. 'No usable sandbox! Update your kernel or see *', # [30981:30992:0605/200633.041364:ERROR:cert_verify_proc_nss.cc(918)] # CERT_PKIXVerifyCert for localhost failed err=-8179 'CERT_PKIXVerifyCert for localhost failed err=*', # [1:1:0914/130428.060976:ERROR:broker_posix.cc(41)] Invalid node # channel message 'Invalid node channel message', # Qt 5.9.3 # [30217:30229:1124/141512.682110:ERROR: # cert_verify_proc_openssl.cc(212)] # X509 Verification error self signed certificate : 18 : 0 : 4 'X509 Verification error self signed certificate : 18 : 0 : 4', # Qt 5.13 # [27789:27805:0325/111821.127349:ERROR:ssl_client_socket_impl.cc(962)] # handshake failed; returned -1, SSL error code 1, net_error -202 'handshake failed; returned -1, SSL error code 1, net_error -202', # Not reproducible anymore? 'Running without the SUID sandbox! *', 'Unable to locate theme engine in module_path: *', 'Could not bind NETLINK socket: Address already in use', # Started appearing in sessions.feature with Qt 5.8... 'Invalid node channel message *', # Makes tests fail on Quantumcross' machine ('CreatePlatformSocket() returned an error, errno=97: Address family' 'not supported by protocol'), # Qt 5.9 with debug Chromium # [28121:28121:0605/191637.407848:WARNING:resource_bundle_qt.cpp(114)] # locale_file_path.empty() for locale 'locale_file_path.empty() for locale', # [26598:26598:0605/191429.639416:WARNING:audio_manager.cc(317)] # Multiple instances of AudioManager detected 'Multiple instances of AudioManager detected', # [25775:25788:0605/191240.931551:ERROR:quarantine_linux.cc(33)] # Could not set extended attribute user.xdg.origin.url on file # /tmp/pytest-of-florian/pytest-32/test_webengine_download_suffix0/ # downloads/download.bin: Operation not supported ('Could not set extended attribute user.xdg.* on file *: ' 'Operation not supported*'), # [5947:5947:0605/192837.856931:ERROR:render_process_impl.cc(112)] # WebFrame LEAKED 1 TIMES 'WebFrame LEAKED 1 TIMES', # Qt 5.10 with debug Chromium # [1016/155149.941048:WARNING:stack_trace_posix.cc(625)] Failed to open # file: /home/florian/#14687139 (deleted) # Error: No such file or directory 'Failed to open file: * (deleted)', # macOS on Travis # [5140:5379:0911/063441.239771:ERROR:mach_port_broker.mm(175)] # Unknown process 5176 is sending Mach IPC messages! 'Unknown process * is sending Mach IPC messages!', # [5205:44547:0913/142945.003625:ERROR:node_controller.cc(1268)] Error # on receiving Mach ports FFA56F125F699ADB.E28E252911A8704B. Dropping # message. 'Error on receiving Mach ports *. Dropping message.', # [2734:2746:1107/131154.072032:ERROR:nss_ocsp.cc(591)] No # URLRequestContext for NSS HTTP handler. host: ocsp.digicert.com 'No URLRequestContext for NSS HTTP handler. host: *', # https://bugreports.qt.io/browse/QTBUG-66661 # [23359:23359:0319/115812.168578:WARNING: # render_frame_host_impl.cc(2744)] OnDidStopLoading was called twice. 'OnDidStopLoading was called twice.', # [30412:30412:0323/074933.387250:ERROR:node_channel.cc(899)] Dropping # message on closed channel. 'Dropping message on closed channel.', # [2204:1408:0703/113804.788:ERROR: # gpu_process_transport_factory.cc(1019)] Lost UI shared context. 'Lost UI shared context.', # Qt 5.12 # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70702 # [32123:32123:0923/224739.457307:ERROR:in_progress_cache_impl.cc(192)] # Cache is not initialized, cannot RetrieveEntry. 'Cache is not initialized, cannot RetrieveEntry.', 'Cache is not initialized, cannot AddOrReplaceEntry.', # [10518:10518:0924/121250.186121:WARNING: # render_frame_host_impl.cc(431)] # InterfaceRequest was dropped, the document is no longer active: # content.mojom.RendererAudioOutputStreamFactory 'InterfaceRequest was dropped, the document is no longer active: ' 'content.mojom.RendererAudioOutputStreamFactory', # [1920:2168:0225/112442.664:ERROR:in_progress_cache_impl.cc(124)] # Could not write download entries to file: C:\Users\appveyor\AppData\ # Local\Temp\1\qutebrowser-basedir-1l3jmxq4\data\webengine\ # in_progress_download_metadata_store 'Could not write download entries to file: *', # Qt 5.13 # [32651:32651:0325/130146.300817:WARNING: # render_frame_host_impl.cc(486)] # InterfaceRequest was dropped, the document is no longer active: # resource_coordinator.mojom.FrameCoordinationUnit 'InterfaceRequest was dropped, the document is no longer active: ' 'resource_coordinator.mojom.FrameCoordinationUnit', # Qt 5.14 # [1:7:1119/162200.709920:ERROR:command_buffer_proxy_impl.cc(124)] # ContextResult::kTransientFailure: Failed to send # GpuChannelMsg_CreateCommandBuffer. 'ContextResult::kTransientFailure: Failed to send ' 'GpuChannelMsg_CreateCommandBuffer.', # [156330:156350:1121/120052.060701:WARNING: # important_file_writer.cc(97)] # temp file failure: /home/florian/.local/share/qutebrowser/ # qutebrowser/QtWebEngine/Default/user_prefs.json : could not create # temporary file: No such file or directory (2) 'temp file failure: */qutebrowser/qutebrowser/QtWebEngine/Default/' 'user_prefs.json : could not create temporary file: No such file or ' 'directory (2)', # [156330:156330:1121/120052.602236:ERROR: # viz_process_transport_factory.cc(331)] # Switching to software compositing. 'Switching to software compositing.', # [160686:160712:1121/121226.457866:ERROR:surface_manager.cc(438)] # Old/orphaned temporary reference to # SurfaceId(FrameSinkId[](5, 2), LocalSurfaceId(8, 1, 7C3A...)) 'Old/orphaned temporary reference to ' 'SurfaceId(FrameSinkId[](*), LocalSurfaceId(*))', # [79680:79705:0111/151113.071008:WARNING: # important_file_writer.cc(97)] temp file failure: # /tmp/qutebrowser-basedir-gwkvqpyp/data/webengine/user_prefs.json : # could not create temporary file: No such file or directory (2) # (Only in debug builds) # https://bugreports.qt.io/browse/QTBUG-78319 'temp file failure: * : could not create temporary file: No such file ' 'or directory (2)', # Travis # test_ssl_error_with_contentssl_strict__true # [5306:5324:0417/151739.362362:ERROR:address_tracker_linux.cc(171)] # Could not bind NETLINK socket: Address already in use (98) 'Could not bind NETLINK socket: Address already in use (98)', # Qt 5.15 with AppVeyor # [2968:3108:0601/123442.125:ERROR:mf_helpers.cc(14)] Error in # dxva_video_decode_accelerator_win.cc on line 517 'Error in dxva_video_decode_accelerator_win.cc on line 517', # Qt 5.15 and debug build # [134188:134199:0609/132454.797229:WARNING: # simple_synchronous_entry.cc(1389)] # Could not open platform files for entry. # [134151:134187:0609/132456.754321:ERROR:process_posix.cc(333)] # Unable to terminate process 134188: No such process (3) # [134151:134187:0609/132456.754414:WARNING:internal_linux.cc(64)] # Failed to read /proc/134188/stat 'Could not open platform files for entry.', 'Unable to terminate process *: No such process (3)', 'Failed to read /proc/*/stat', # Qt 5.15.1 debug build (Chromium 83) # '[314297:7:0929/214605.491958:ERROR:context_provider_command_buffer.cc(145)] # GpuChannelHost failed to create command buffer.' 'GpuChannelHost failed to create command buffer.', # [338691:4:0929/220114.488847:WARNING:ipc_message_attachment_set.cc(49)] # MessageAttachmentSet destroyed with unconsumed attachments: 0/1 'MessageAttachmentSet destroyed with unconsumed attachments: *', # GitHub Actions with Qt 5.15.1 ('SharedImageManager::ProduceGLTexture: Trying to produce a ' 'representation from a non-existent mailbox. *'), ('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : ' 'DoCreateAndTexStorage2DSharedImageINTERNAL: invalid mailbox name'), ('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : ' 'DoBeginSharedImageAccessCHROMIUM: bound texture is not a shared image' ), ('[.DisplayCompositor]RENDER WARNING: texture bound to texture unit 0 is ' 'not renderable. It might be non-power-of-2 or have incompatible texture ' 'filtering (maybe)?'), ('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : ' 'DoEndSharedImageAccessCHROMIUM: bound texture is not a shared image' ), # WebRTC with Qt 5.13 / 5.14 'Failed to query stereo recording.', 'Accepting maxRetransmits = -1 for backwards compatibility', 'Accepting maxRetransmitTime = -1 for backwards compatibility', # Windows N: # https://github.com/microsoft/playwright/issues/2901 ('DXVAVDA fatal error: could not LoadLibrary: *: The specified ' 'module could not be found. (0x7E)'), # Qt 5.15.3 dev build r'Duplicate id found. Reassigning from * to *', ] return any( testutils.pattern_match(pattern=pattern, value=message) for pattern in ignored_messages)
def test_pattern_match(pattern, value, expected): assert testutils.pattern_match(pattern=pattern, value=value) == expected