hydrus/hydrus/test/TestController.py

1028 lines
30 KiB
Python
Raw Normal View History

2019-03-13 21:04:21 +00:00
import collections
import os
import threading
import tempfile
import time
import traceback
import unittest
2020-07-29 20:52:44 +00:00
from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
2020-04-22 21:00:35 +00:00
from hydrus.core import HydrusConstants as HC
2020-07-29 20:52:44 +00:00
from hydrus.core import HydrusData
from hydrus.core import HydrusExceptions
2020-04-22 21:00:35 +00:00
from hydrus.core import HydrusGlobals as HG
2020-07-29 20:52:44 +00:00
from hydrus.core import HydrusPaths
from hydrus.core import HydrusPubSub
from hydrus.core import HydrusSessions
2023-11-08 21:42:59 +00:00
from hydrus.core import HydrusTemp
2020-07-29 20:52:44 +00:00
from hydrus.core import HydrusThreading
2020-04-22 21:00:35 +00:00
from hydrus.client import ClientAPI
2020-07-29 20:52:44 +00:00
from hydrus.client import ClientConstants as CC
2020-04-22 21:00:35 +00:00
from hydrus.client import ClientDefaults
from hydrus.client import ClientFiles
2023-08-30 16:25:24 +00:00
from hydrus.client import ClientFilesPhysical
2024-02-07 21:22:05 +00:00
from hydrus.client import ClientGlobals as CG
2020-07-29 20:52:44 +00:00
from hydrus.client import ClientOptions
2020-04-22 21:00:35 +00:00
from hydrus.client import ClientManagers
2020-07-29 20:52:44 +00:00
from hydrus.client import ClientServices
from hydrus.client import ClientThreading
2023-06-28 20:29:14 +00:00
from hydrus.client.caches import ClientCaches
2020-07-29 20:52:44 +00:00
from hydrus.client.gui import QtPorting as QP
2020-09-02 21:10:41 +00:00
from hydrus.client.gui import ClientGUISplash
2020-07-15 20:52:09 +00:00
from hydrus.client.gui.lists import ClientGUIListManager
2021-06-30 21:27:35 +00:00
from hydrus.client.importing import ClientImportFiles
2024-01-31 21:20:50 +00:00
from hydrus.client.metadata import ClientContentUpdates
from hydrus.client.metadata import ClientTagsHandling
2020-04-22 21:00:35 +00:00
from hydrus.client.networking import ClientNetworking
from hydrus.client.networking import ClientNetworkingBandwidth
from hydrus.client.networking import ClientNetworkingDomain
from hydrus.client.networking import ClientNetworkingLogin
from hydrus.client.networking import ClientNetworkingSessions
2020-07-29 20:52:44 +00:00
2020-04-22 21:00:35 +00:00
from hydrus.test import TestClientAPI
from hydrus.test import TestClientConstants
from hydrus.test import TestClientDaemons
from hydrus.test import TestClientData
from hydrus.test import TestClientDB
from hydrus.test import TestClientDBDuplicates
2020-08-19 22:38:20 +00:00
from hydrus.test import TestClientDBTags
2023-08-30 16:25:24 +00:00
from hydrus.test import TestClientFileStorage
2020-04-22 21:00:35 +00:00
from hydrus.test import TestClientImageHandling
from hydrus.test import TestClientImportOptions
from hydrus.test import TestClientImportSubscriptions
from hydrus.test import TestClientListBoxes
2022-10-26 20:43:00 +00:00
from hydrus.test import TestClientMetadataMigration
2020-04-22 21:00:35 +00:00
from hydrus.test import TestClientMigration
from hydrus.test import TestClientNetworking
2020-05-13 19:03:16 +00:00
from hydrus.test import TestClientParsing
2020-04-22 21:00:35 +00:00
from hydrus.test import TestClientTags
from hydrus.test import TestClientThreading
from hydrus.test import TestDialogs
2021-03-17 21:59:28 +00:00
from hydrus.test import TestHydrusData
2020-11-11 22:20:16 +00:00
from hydrus.test import TestHydrusNATPunch
2020-04-22 21:00:35 +00:00
from hydrus.test import TestHydrusNetworking
2023-11-29 22:27:53 +00:00
from hydrus.test import TestHydrusPaths
2020-04-22 21:00:35 +00:00
from hydrus.test import TestHydrusSerialisable
from hydrus.test import TestHydrusServer
from hydrus.test import TestHydrusSessions
2023-03-22 20:28:10 +00:00
from hydrus.test import TestHydrusTags
2023-05-03 20:34:44 +00:00
from hydrus.test import TestHydrusTime
2020-04-22 21:00:35 +00:00
from hydrus.test import TestServerDB
2019-03-13 21:04:21 +00:00
DB_DIR = None
tiniest_gif = b'\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x00\xFF\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00\x3B'
LOCAL_RATING_LIKE_SERVICE_KEY = HydrusData.GenerateKey()
LOCAL_RATING_NUMERICAL_SERVICE_KEY = HydrusData.GenerateKey()
2023-03-08 21:52:17 +00:00
LOCAL_RATING_INCDEC_SERVICE_KEY = HydrusData.GenerateKey()
2019-03-13 21:04:21 +00:00
class MockController( object ):
def __init__( self ):
self.new_options = ClientOptions.ClientOptions()
def CallToThread( self, callable, *args, **kwargs ):
return HG.test_controller.CallToThread( callable, *args, **kwargs )
def JustWokeFromSleep( self ):
return False
def pub( self, *args, **kwargs ):
pass
def sub( self, *args, **kwargs ):
pass
class MockServicesManager( object ):
def __init__( self, services ):
self._service_keys_to_services = { service.GetServiceKey() : service for service in services }
def GetName( self, service_key ):
return self._service_keys_to_services[ service_key ].GetName()
def GetService( self, service_key ):
return self._service_keys_to_services[ service_key ]
def ServiceExists( self, service_key ):
return service_key in self._service_keys_to_services
class FakeWebSessionManager():
def EnsureLoggedIn( self, name ):
pass
def GetCookies( self, *args, **kwargs ):
return { 'session_cookie' : 'blah' }
2019-11-14 03:56:30 +00:00
class TestFrame( QW.QWidget ):
2019-03-13 21:04:21 +00:00
def __init__( self ):
2019-11-14 03:56:30 +00:00
QW.QWidget.__init__( self, None )
2019-03-13 21:04:21 +00:00
def SetPanel( self, panel ):
2019-11-14 03:56:30 +00:00
vbox = QP.VBoxLayout()
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
QP.AddToLayout( vbox, panel, CC.FLAGS_EXPAND_BOTH_WAYS )
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
self.setLayout( vbox )
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
self.show()
2019-03-13 21:04:21 +00:00
only_run = None
class Controller( object ):
def __init__( self, win, only_run ):
2021-01-07 01:10:01 +00:00
self.app = win
2019-03-13 21:04:21 +00:00
self.win = win
self.only_run = only_run
2021-06-30 21:27:35 +00:00
self.run_finished = False
self.was_successful = False
self._test_db = None
2019-03-13 21:04:21 +00:00
self.db_dir = tempfile.mkdtemp()
2023-11-08 21:42:59 +00:00
self._hydrus_temp_dir = HydrusTemp.InitialiseHydrusTempDir()
2019-03-13 21:04:21 +00:00
global DB_DIR
DB_DIR = self.db_dir
self._server_files_dir = os.path.join( self.db_dir, 'server_files' )
self._updates_dir = os.path.join( self.db_dir, 'test_updates' )
client_files_default = os.path.join( self.db_dir, 'client_files' )
HydrusPaths.MakeSureDirectoryExists( self._server_files_dir )
HydrusPaths.MakeSureDirectoryExists( self._updates_dir )
HydrusPaths.MakeSureDirectoryExists( client_files_default )
HG.controller = self
HG.server_controller = self
HG.test_controller = self
2024-02-07 21:22:05 +00:00
CG.client_controller = self
2019-10-09 22:03:03 +00:00
self.db = self
2019-03-13 21:04:21 +00:00
self.gui = self
2020-09-02 21:10:41 +00:00
self.frame_splash_status = ClientGUISplash.FrameSplashStatus()
2019-03-13 21:04:21 +00:00
self._call_to_threads = []
2024-02-14 21:20:24 +00:00
self._pubsub = HydrusPubSub.HydrusPubSub( lambda o: True )
2019-03-13 21:04:21 +00:00
2019-03-27 22:01:02 +00:00
self.new_options = ClientOptions.ClientOptions()
2019-03-13 21:04:21 +00:00
HC.options = ClientDefaults.GetClientDefaultOptions()
self.options = HC.options
def show_text( text ): pass
HydrusData.ShowText = show_text
2021-08-18 21:10:01 +00:00
self._name_read_responses = {}
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
self._name_read_responses[ 'messaging_sessions' ] = []
self._name_read_responses[ 'options' ] = ClientDefaults.GetClientDefaultOptions()
self._name_read_responses[ 'file_system_predicates' ] = []
self._name_read_responses[ 'media_results' ] = []
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
self._param_read_responses = {}
2023-06-07 20:07:22 +00:00
self.example_like_rating_service_key = LOCAL_RATING_LIKE_SERVICE_KEY
self.example_numerical_rating_service_key = LOCAL_RATING_NUMERICAL_SERVICE_KEY
self.example_incdec_rating_service_key = LOCAL_RATING_INCDEC_SERVICE_KEY
2022-11-23 21:01:41 +00:00
self.example_file_repo_service_key_1 = HydrusData.GenerateKey()
self.example_file_repo_service_key_2 = HydrusData.GenerateKey()
2019-03-13 21:04:21 +00:00
self.example_tag_repo_service_key = HydrusData.GenerateKey()
2022-10-05 21:00:47 +00:00
self.example_ipfs_service_key = HydrusData.GenerateKey()
2019-03-13 21:04:21 +00:00
services = []
services.append( ClientServices.GenerateService( CC.CLIENT_API_SERVICE_KEY, HC.CLIENT_API_SERVICE, 'client api' ) )
services.append( ClientServices.GenerateService( CC.COMBINED_LOCAL_FILE_SERVICE_KEY, HC.COMBINED_LOCAL_FILE, 'all local files' ) )
2022-05-25 21:30:53 +00:00
services.append( ClientServices.GenerateService( CC.COMBINED_LOCAL_MEDIA_SERVICE_KEY, HC.COMBINED_LOCAL_MEDIA, 'all my files' ) )
2019-03-13 21:04:21 +00:00
services.append( ClientServices.GenerateService( CC.LOCAL_FILE_SERVICE_KEY, HC.LOCAL_FILE_DOMAIN, 'my files' ) )
2022-05-04 21:40:27 +00:00
services.append( ClientServices.GenerateService( CC.LOCAL_UPDATE_SERVICE_KEY, HC.LOCAL_FILE_UPDATE_DOMAIN, 'repository updates' ) )
2019-03-13 21:04:21 +00:00
services.append( ClientServices.GenerateService( CC.TRASH_SERVICE_KEY, HC.LOCAL_FILE_TRASH_DOMAIN, 'trash' ) )
2019-09-18 22:40:39 +00:00
services.append( ClientServices.GenerateService( CC.DEFAULT_LOCAL_TAG_SERVICE_KEY, HC.LOCAL_TAG, 'my tags' ) )
2022-11-23 21:01:41 +00:00
services.append( ClientServices.GenerateService( self.example_file_repo_service_key_1, HC.FILE_REPOSITORY, 'example file repo 1' ) )
services.append( ClientServices.GenerateService( self.example_file_repo_service_key_2, HC.FILE_REPOSITORY, 'example file repo 2' ) )
2019-03-13 21:04:21 +00:00
services.append( ClientServices.GenerateService( self.example_tag_repo_service_key, HC.TAG_REPOSITORY, 'example tag repo' ) )
services.append( ClientServices.GenerateService( CC.COMBINED_TAG_SERVICE_KEY, HC.COMBINED_TAG, 'all known tags' ) )
2021-05-27 00:09:06 +00:00
services.append( ClientServices.GenerateService( CC.COMBINED_FILE_SERVICE_KEY, HC.COMBINED_FILE, 'all known files' ) )
2019-03-13 21:04:21 +00:00
services.append( ClientServices.GenerateService( LOCAL_RATING_LIKE_SERVICE_KEY, HC.LOCAL_RATING_LIKE, 'example local rating like service' ) )
services.append( ClientServices.GenerateService( LOCAL_RATING_NUMERICAL_SERVICE_KEY, HC.LOCAL_RATING_NUMERICAL, 'example local rating numerical service' ) )
2023-03-08 21:52:17 +00:00
services.append( ClientServices.GenerateService( LOCAL_RATING_INCDEC_SERVICE_KEY, HC.LOCAL_RATING_INCDEC, 'example local rating inc/dec service' ) )
2022-10-05 21:00:47 +00:00
services.append( ClientServices.GenerateService( self.example_ipfs_service_key, HC.IPFS, 'example ipfs service' ) )
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
self._name_read_responses[ 'services' ] = services
2019-03-13 21:04:21 +00:00
2023-08-30 16:25:24 +00:00
client_files_subfolders = []
2019-03-13 21:04:21 +00:00
2023-09-13 18:26:31 +00:00
base_location = ClientFilesPhysical.FilesStorageBaseLocation( client_files_default, 1 )
2019-03-13 21:04:21 +00:00
for prefix in HydrusData.IterateHexPrefixes():
2019-03-27 22:01:02 +00:00
for c in ( 'f', 't' ):
2019-03-13 21:04:21 +00:00
2023-09-13 18:26:31 +00:00
client_files_subfolders.append( ClientFilesPhysical.FilesStorageSubfolder( c + prefix, base_location ) )
2019-03-13 21:04:21 +00:00
2023-08-30 16:25:24 +00:00
self._name_read_responses[ 'client_files_subfolders' ] = client_files_subfolders
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
self._name_read_responses[ 'sessions' ] = []
self._name_read_responses[ 'tag_parents' ] = {}
self._name_read_responses[ 'tag_siblings_all_ideals' ] = {}
self._name_read_responses[ 'inbox_hashes' ] = set()
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
self._read_call_args = collections.defaultdict( list )
self._write_call_args = collections.defaultdict( list )
2019-03-13 21:04:21 +00:00
self._managers = {}
2020-07-15 20:52:09 +00:00
self.column_list_manager = ClientGUIListManager.ColumnListManager()
self.services_manager = ClientServices.ServicesManager( self )
2019-05-22 22:35:06 +00:00
self.client_files_manager = ClientFiles.ClientFilesManager( self )
2019-03-13 21:04:21 +00:00
self.parsing_cache = ClientCaches.ParsingCache()
bandwidth_manager = ClientNetworkingBandwidth.NetworkBandwidthManager()
session_manager = ClientNetworkingSessions.NetworkSessionManager()
domain_manager = ClientNetworkingDomain.NetworkDomainManager()
ClientDefaults.SetDefaultDomainManagerData( domain_manager )
login_manager = ClientNetworkingLogin.NetworkLoginManager()
self.network_engine = ClientNetworking.NetworkEngine( self, bandwidth_manager, session_manager, domain_manager, login_manager )
self.CallToThreadLongRunning( self.network_engine.MainLoop )
self.tag_display_manager = ClientTagsHandling.TagDisplayManager()
2020-10-21 22:22:10 +00:00
2019-12-05 05:29:32 +00:00
self._managers[ 'undo' ] = ClientManagers.UndoManager( self )
2021-05-05 20:12:11 +00:00
self._caches = {}
self._caches[ 'images' ] = ClientCaches.ImageRendererCache( self )
self._caches[ 'image_tiles' ] = ClientCaches.ImageTileCache( self )
self._caches[ 'thumbnail' ] = ClientCaches.ThumbnailCache( self )
2019-03-13 21:04:21 +00:00
self.server_session_manager = HydrusSessions.HydrusSessionManagerServer()
2019-12-05 05:29:32 +00:00
self.bitmap_manager = ClientManagers.BitmapManager( self )
2019-04-17 21:51:50 +00:00
2019-03-13 21:04:21 +00:00
self.client_api_manager = ClientAPI.APIManager()
self._cookies = {}
self._job_scheduler = HydrusThreading.JobScheduler( self )
self._job_scheduler.start()
def _GetCallToThread( self ):
for call_to_thread in self._call_to_threads:
if not call_to_thread.CurrentlyWorking():
return call_to_thread
if len( self._call_to_threads ) > 100:
raise Exception( 'Too many call to threads!' )
call_to_thread = HydrusThreading.THREADCallToThread( self, 'CallToThread' )
self._call_to_threads.append( call_to_thread )
call_to_thread.start()
return call_to_thread
2019-11-14 03:56:30 +00:00
def _SetupQt( self ):
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
self.locale = QC.QLocale() # Very important to init this here and keep it non garbage collected
2019-03-13 21:04:21 +00:00
2020-03-11 21:52:11 +00:00
CC.GlobalPixmaps()
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
self.frame_icon_pixmap = QG.QPixmap( os.path.join( HC.STATIC_DIR, 'hydrus_32_non-transparent.png' ) )
2019-03-13 21:04:21 +00:00
def pub( self, topic, *args, **kwargs ):
pass
def pubimmediate( self, topic, *args, **kwargs ):
self._pubsub.pubimmediate( topic, *args, **kwargs )
def sub( self, object, method_name, topic ):
self._pubsub.sub( object, method_name, topic )
def AcquirePageKey( self ):
return HydrusData.GenerateKey()
2019-11-14 03:56:30 +00:00
def CallBlockingToQt( self, win, func, *args, **kwargs ):
2019-03-13 21:04:21 +00:00
2023-11-15 22:40:54 +00:00
def qt_code( win: QW.QWidget, job_status: ClientThreading.JobStatus ):
2019-03-13 21:04:21 +00:00
try:
2019-11-14 03:56:30 +00:00
if win is not None and not QP.isValid( win ):
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
raise HydrusExceptions.QtDeadWindowException('Parent Window was destroyed before Qt command was called!')
2019-03-13 21:04:21 +00:00
result = func( *args, **kwargs )
2023-11-15 22:40:54 +00:00
job_status.SetVariable( 'result', result )
2019-03-13 21:04:21 +00:00
2020-05-06 21:31:41 +00:00
except ( HydrusExceptions.QtDeadWindowException, HydrusExceptions.DBCredentialsException, HydrusExceptions.ShutdownException ) as e:
2019-03-13 21:04:21 +00:00
2023-11-15 22:40:54 +00:00
job_status.SetErrorException( e )
2019-03-13 21:04:21 +00:00
except Exception as e:
2023-11-15 22:40:54 +00:00
job_status.SetErrorException( e )
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
HydrusData.Print( 'CallBlockingToQt just caught this error:' )
2019-03-13 21:04:21 +00:00
HydrusData.DebugPrint( traceback.format_exc() )
finally:
2023-11-15 22:40:54 +00:00
job_status.Finish()
2019-03-13 21:04:21 +00:00
2023-11-29 22:27:53 +00:00
job_status = ClientThreading.JobStatus( cancellable = True, cancel_on_shutdown = False )
2019-03-13 21:04:21 +00:00
2023-11-15 22:40:54 +00:00
QP.CallAfter( qt_code, win, job_status )
2019-03-13 21:04:21 +00:00
2023-11-15 22:40:54 +00:00
while not job_status.IsDone():
2019-03-13 21:04:21 +00:00
if HG.model_shutdown:
raise HydrusExceptions.ShutdownException( 'Application is shutting down!' )
time.sleep( 0.05 )
2023-11-15 22:40:54 +00:00
if job_status.HasVariable( 'result' ):
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
# result can be None, for qt_code that has no return variable
2019-03-13 21:04:21 +00:00
2023-11-15 22:40:54 +00:00
result = job_status.GetIfHasVariable( 'result' )
2019-03-13 21:04:21 +00:00
return result
2023-11-15 22:40:54 +00:00
if job_status.HadError():
2020-03-04 22:12:53 +00:00
2023-11-15 22:40:54 +00:00
e = job_status.GetErrorException()
2019-03-13 21:04:21 +00:00
2020-03-04 22:12:53 +00:00
raise e
2019-03-13 21:04:21 +00:00
raise HydrusExceptions.ShutdownException()
def CallToThread( self, callable, *args, **kwargs ):
call_to_thread = self._GetCallToThread()
call_to_thread.put( callable, *args, **kwargs )
CallToThreadLongRunning = CallToThread
2021-06-23 21:11:38 +00:00
def CallAfterQtSafe( self, window, label, func, *args, **kwargs ):
2020-03-11 21:52:11 +00:00
2021-06-23 21:11:38 +00:00
self.CallLaterQtSafe( window, 0, label, func, *args, **kwargs )
2020-03-11 21:52:11 +00:00
2019-03-13 21:04:21 +00:00
def CallLater( self, initial_delay, func, *args, **kwargs ):
call = HydrusData.Call( func, *args, **kwargs )
2020-02-26 22:28:52 +00:00
job = HydrusThreading.SingleJob( self, self._job_scheduler, initial_delay, call )
2019-03-13 21:04:21 +00:00
self._job_scheduler.AddJob( job )
return job
2021-06-23 21:11:38 +00:00
def CallLaterQtSafe( self, window, initial_delay, label, func, *args, **kwargs ):
2019-03-13 21:04:21 +00:00
call = HydrusData.Call( func, *args, **kwargs )
2021-06-23 21:11:38 +00:00
call.SetLabel( label )
job = ClientThreading.QtAwareJob( self, self._job_scheduler, window, initial_delay, call )
2019-03-13 21:04:21 +00:00
self._job_scheduler.AddJob( job )
return job
2021-06-23 21:11:38 +00:00
def CallRepeating( self, initial_delay, period, label, func, *args, **kwargs ):
2019-03-13 21:04:21 +00:00
call = HydrusData.Call( func, *args, **kwargs )
job = HydrusThreading.RepeatingJob( self, self._job_scheduler, initial_delay, period, call )
self._job_scheduler.AddJob( job )
return job
2021-06-23 21:11:38 +00:00
def CallRepeatingQtSafe( self, window, initial_delay, period, label, func, *args, **kwargs ):
2019-03-13 21:04:21 +00:00
call = HydrusData.Call( func, *args, **kwargs )
2019-11-14 03:56:30 +00:00
job = ClientThreading.QtAwareRepeatingJob(self, self._job_scheduler, window, initial_delay, period, call)
2019-03-13 21:04:21 +00:00
self._job_scheduler.AddJob( job )
return job
2021-08-18 21:10:01 +00:00
def ClearReads( self, name ):
if name in self._read_call_args:
del self._read_call_args[ name ]
2021-06-30 21:27:35 +00:00
def ClearTestDB( self ):
self._test_db = None
2019-03-13 21:04:21 +00:00
def ClearWrites( self, name ):
2021-08-18 21:10:01 +00:00
if name in self._write_call_args:
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
del self._write_call_args[ name ]
2019-03-13 21:04:21 +00:00
def DBCurrentlyDoingJob( self ):
return False
def DoingFastExit( self ):
return False
2021-05-05 20:12:11 +00:00
def GetCache( self, name ):
return self._caches[ name ]
2019-08-21 21:34:01 +00:00
def GetCurrentSessionPageAPIInfoDict( self ):
2019-06-05 19:42:39 +00:00
return {
"name" : "top pages notebook",
2019-06-26 21:27:18 +00:00
"page_key" : "3b28d8a59ec61834325eb6275d9df012860a1ecfd9e1246423059bc47fb6d5bd",
2019-06-05 19:42:39 +00:00
"page_type" : 10,
"selected" : True,
"pages" : [
2019-06-26 21:27:18 +00:00
{
"name" : "files",
"page_key" : "d436ff5109215199913705eb9a7669d8a6b67c52e41c3b42904db083255ca84d",
"page_type" : 6,
"selected" : False
},
{
"name" : "thread watcher",
"page_key" : "40887fa327edca01e1d69b533dddba4681b2c43e0b4ebee0576177852e8c32e7",
"page_type" : 9,
"selected" : False
},
{
"name" : "pages",
"page_key" : "2ee7fa4058e1e23f2bd9e915cdf9347ae90902a8622d6559ba019a83a785c4dc",
"page_type" : 10,
"selected" : True,
"pages" : [
{
"name" : "urls",
"page_key" : "9fe22cb760d9ee6de32575ed9f27b76b4c215179cf843d3f9044efeeca98411f",
"page_type" : 7,
"selected" : True
},
{
2019-06-05 19:42:39 +00:00
"name" : "files",
2019-06-26 21:27:18 +00:00
"page_key" : "2977d57fc9c588be783727bcd54225d577b44e8aa2f91e365a3eb3c3f580dc4e",
2019-06-05 19:42:39 +00:00
"page_type" : 6,
"selected" : False
2019-06-26 21:27:18 +00:00
}
]
}
2019-06-05 19:42:39 +00:00
]
}
2019-03-13 21:04:21 +00:00
def GetFilesDir( self ):
return self._server_files_dir
2020-07-15 20:52:09 +00:00
def GetMainTLW( self ):
return self.win
2019-03-13 21:04:21 +00:00
def GetNewOptions( self ):
return self.new_options
def GetManager( self, manager_type ):
return self._managers[ manager_type ]
2019-08-21 21:34:01 +00:00
def GetPageAPIInfoDict( self, page_key, simple ):
return {}
2021-08-18 21:10:01 +00:00
def GetRead( self, name ):
read = self._read_call_args[ name ]
del self._read_call_args[ name ]
return read
2023-11-08 21:42:59 +00:00
def GetHydrusTempDir( self ):
return self._hydrus_temp_dir
2019-03-13 21:04:21 +00:00
def GetWrite( self, name ):
2021-08-18 21:10:01 +00:00
write = self._write_call_args[ name ]
2019-03-13 21:04:21 +00:00
2021-08-18 21:10:01 +00:00
del self._write_call_args[ name ]
2019-03-13 21:04:21 +00:00
return write
2020-09-16 20:46:54 +00:00
def ImportURLFromAPI( self, url, filterable_tags, additional_service_keys_to_tags, destination_page_name, destination_page_key, show_destination_page ):
2019-03-13 21:04:21 +00:00
2024-03-27 21:47:50 +00:00
normalised_url = self.network_engine.domain_manager.NormaliseURL( url, for_server = True )
2019-03-13 21:04:21 +00:00
human_result_text = '"{}" URL added successfully.'.format( normalised_url )
2020-09-16 20:46:54 +00:00
self.Write( 'import_url_test', url, filterable_tags, additional_service_keys_to_tags, destination_page_name, destination_page_key, show_destination_page )
2019-03-13 21:04:21 +00:00
return ( normalised_url, human_result_text )
def IsBooted( self ):
return True
2021-05-27 00:09:06 +00:00
def IsConnected( self ):
2022-10-12 20:18:22 +00:00
return False
2021-05-27 00:09:06 +00:00
2019-03-13 21:04:21 +00:00
def IsCurrentPage( self, page_key ):
return False
def IsFirstStart( self ):
return True
2020-01-22 21:04:43 +00:00
def isFullScreen( self ):
return True # hackery for another test
2019-03-13 21:04:21 +00:00
def IShouldRegularlyUpdate( self, window ):
return True
def JustWokeFromSleep( self ):
return False
2024-05-08 20:25:53 +00:00
def LastShutdownWasBad( self ):
return False
2019-03-13 21:04:21 +00:00
def PageAlive( self, page_key ):
return False
def PageClosedButNotDestroyed( self, page_key ):
return False
2019-10-09 22:03:03 +00:00
def PauseAndDisconnect( self, pause_and_disconnect ):
pass
2019-03-13 21:04:21 +00:00
def Read( self, name, *args, **kwargs ):
2021-08-18 21:10:01 +00:00
self._read_call_args[ name ].append( ( args, kwargs ) )
2021-06-30 21:27:35 +00:00
if self._test_db is not None:
return self._test_db.Read( name, *args, **kwargs )
try:
2021-08-18 21:10:01 +00:00
if ( name, args ) in self._param_read_responses:
2021-08-18 21:10:01 +00:00
return self._param_read_responses[ ( name, args ) ]
except:
pass
result = self._name_read_responses[ name ]
if isinstance( result, Exception ):
raise HydrusExceptions.DBException( result, str( result ), 'test trace' )
return result
2019-03-13 21:04:21 +00:00
def RegisterUIUpdateWindow( self, window ):
pass
def ReleasePageKey( self, page_key ):
pass
def ReportDataUsed( self, num_bytes ):
pass
def ReportRequestUsed( self ):
pass
2021-06-09 20:28:09 +00:00
def ResetIdleTimer( self ):
pass
def ResetIdleTimerFromClientAPI( self ):
pass
2019-03-13 21:04:21 +00:00
def Run( self, window ):
2019-11-14 03:56:30 +00:00
# we are in Qt thread here, we can do this
self._SetupQt()
2019-03-13 21:04:21 +00:00
if self.only_run is None:
run_all = True
else:
run_all = False
# the gui stuff runs fine on its own but crashes in the full test if it is not early, wew
# something to do with the delayed button clicking stuff
2020-05-20 21:36:02 +00:00
module_lookup = collections.defaultdict( list )
module_lookup[ 'all' ] = [
TestDialogs,
TestClientListBoxes,
TestClientAPI,
TestClientDaemons,
TestClientConstants,
TestClientData,
2023-08-30 16:25:24 +00:00
TestClientFileStorage,
2020-05-20 21:36:02 +00:00
TestClientImportOptions,
TestClientParsing,
TestClientTags,
TestClientThreading,
TestHydrusSerialisable,
TestHydrusSessions,
TestClientDB,
TestServerDB,
TestClientDBDuplicates,
2020-08-19 22:38:20 +00:00
TestClientDBTags,
2021-03-17 21:59:28 +00:00
TestHydrusData,
2023-11-29 22:27:53 +00:00
TestHydrusPaths,
2023-05-03 20:34:44 +00:00
TestHydrusTime,
2020-11-11 22:20:16 +00:00
TestHydrusNATPunch,
2020-05-20 21:36:02 +00:00
TestClientNetworking,
TestHydrusNetworking,
TestClientImportSubscriptions,
TestClientImageHandling,
2022-10-26 20:43:00 +00:00
TestClientMetadataMigration,
2020-05-20 21:36:02 +00:00
TestClientMigration,
2023-03-22 20:28:10 +00:00
TestHydrusTags,
2020-05-20 21:36:02 +00:00
TestHydrusServer
]
module_lookup[ 'gui' ] = [
TestDialogs,
TestClientListBoxes
]
2022-10-26 20:43:00 +00:00
2020-05-20 21:36:02 +00:00
module_lookup[ 'client_api' ] = [
TestClientAPI
]
module_lookup[ 'daemons' ] = [
TestClientDaemons
]
module_lookup[ 'data' ] = [
TestClientConstants,
TestClientData,
2023-08-30 16:25:24 +00:00
TestClientFileStorage,
2020-05-20 21:36:02 +00:00
TestClientImportOptions,
TestClientParsing,
TestClientTags,
TestClientThreading,
2021-03-17 21:59:28 +00:00
TestHydrusData,
2023-11-29 22:27:53 +00:00
TestHydrusPaths,
2023-03-22 20:28:10 +00:00
TestHydrusTags,
2023-05-03 20:34:44 +00:00
TestHydrusTime,
2020-05-20 21:36:02 +00:00
TestHydrusSerialisable,
TestHydrusSessions
]
2020-12-16 22:29:51 +00:00
module_lookup[ 'tags_fast' ] = [
TestClientTags
]
2020-05-20 21:36:02 +00:00
module_lookup[ 'tags' ] = [
2020-08-19 22:38:20 +00:00
TestClientTags,
TestClientDBTags
2020-05-20 21:36:02 +00:00
]
2021-04-07 21:26:45 +00:00
module_lookup[ 'client_db' ] = [
TestClientDB
]
module_lookup[ 'server_db' ] = [
TestServerDB
]
2020-05-20 21:36:02 +00:00
module_lookup[ 'db' ] = [
TestClientDB,
TestServerDB
]
module_lookup[ 'db_duplicates' ] = [
TestClientDBDuplicates
]
2021-10-13 20:16:57 +00:00
module_lookup[ 'db_tags' ] = [
TestClientDBTags
]
2020-11-11 22:20:16 +00:00
module_lookup[ 'nat' ] = [
TestHydrusNATPunch
]
2020-05-20 21:36:02 +00:00
module_lookup[ 'networking' ] = [
TestClientNetworking,
TestHydrusNetworking
]
module_lookup[ 'import' ] = [
TestClientImportSubscriptions
]
module_lookup[ 'image' ] = [
TestClientImageHandling
]
2022-10-26 20:43:00 +00:00
module_lookup[ 'metadata_migration' ] = [
TestClientMetadataMigration
]
2020-05-20 21:36:02 +00:00
module_lookup[ 'migration' ] = [
TestClientMigration
]
module_lookup[ 'server' ] = [
TestHydrusServer
]
if run_all:
modules = module_lookup[ 'all' ]
2019-03-13 21:04:21 +00:00
2020-05-20 21:36:02 +00:00
else:
2019-03-13 21:04:21 +00:00
2020-05-20 21:36:02 +00:00
modules = module_lookup[ self.only_run ]
2019-03-13 21:04:21 +00:00
2020-05-20 21:36:02 +00:00
suites = [ unittest.TestLoader().loadTestsFromModule( module ) for module in modules ]
2019-03-13 21:04:21 +00:00
suite = unittest.TestSuite( suites )
runner = unittest.TextTestRunner( verbosity = 2 )
2021-01-27 22:14:03 +00:00
runner.failfast = True
2019-03-13 21:04:21 +00:00
def do_it():
try:
2021-06-30 21:27:35 +00:00
result = runner.run( suite )
self.run_finished = True
self.was_successful = result.wasSuccessful()
2019-03-13 21:04:21 +00:00
finally:
2019-11-14 03:56:30 +00:00
QP.CallAfter( self.win.deleteLater )
2019-03-13 21:04:21 +00:00
2019-11-14 03:56:30 +00:00
self.win.show()
2019-03-13 21:04:21 +00:00
test_thread = threading.Thread( target = do_it )
test_thread.start()
def SetParamRead( self, name, args, value ):
2021-08-18 21:10:01 +00:00
self._param_read_responses[ ( name, args ) ] = value
2019-03-13 21:04:21 +00:00
def SetRead( self, name, value ):
2021-08-18 21:10:01 +00:00
self._name_read_responses[ name ] = value
2019-03-13 21:04:21 +00:00
def SetStatusBarDirty( self ):
pass
2021-06-30 21:27:35 +00:00
def SetTestDB( self, db ):
self._test_db = db
2019-03-13 21:04:21 +00:00
def SetWebCookies( self, name, value ):
self._cookies[ name ] = value
2019-06-19 22:08:48 +00:00
def ShouldStopThisWork( self, maintenance_mode, stop_time = None ):
return False
2023-01-04 22:22:08 +00:00
def RefreshPage( self, page_key ):
self.Write( 'refresh_page', page_key )
2019-07-17 22:10:19 +00:00
def ShowPage( self, page_key ):
self.Write( 'show_page', page_key )
2019-03-13 21:04:21 +00:00
def TidyUp( self ):
time.sleep( 2 )
HydrusPaths.DeletePath( self.db_dir )
def WaitUntilModelFree( self ):
return
def WaitUntilViewFree( self ):
return
def Write( self, name, *args, **kwargs ):
2021-06-30 21:27:35 +00:00
if self._test_db is not None:
return self._test_db.Write( name, *args, **kwargs )
2021-08-18 21:10:01 +00:00
self._write_call_args[ name ].append( ( args, kwargs ) )
2019-03-13 21:04:21 +00:00
def WriteSynchronous( self, name, *args, **kwargs ):
2021-08-18 21:10:01 +00:00
self._write_call_args[ name ].append( ( args, kwargs ) )
2019-03-13 21:04:21 +00:00
if name == 'import_file':
( file_import_job, ) = args
if file_import_job.GetHash().hex() == 'a593942cb7ea9ffcd8ccf2f0fa23c338e23bfecd9a3e508dfc0bcf07501ead08': # 'blarg' in sha256 hex
raise Exception( 'File failed to import for some reason!' )
else:
2021-06-30 21:27:35 +00:00
h = file_import_job.GetHash()
if h is None:
h = os.urandom( 32 )
return ClientImportFiles.FileImportStatus( CC.STATUS_SUCCESSFUL_AND_NEW, h, note = 'test note' )
2019-03-13 21:04:21 +00:00