hydrus/include/TestServer.py

484 lines
15 KiB
Python

import ClientConstants as CC
import httplib
import HydrusConstants as HC
import HydrusServer
import HydrusServerResources
import itertools
import os
import ServerConstants as SC
import shutil
import stat
import TestConstants
import time
import threading
import unittest
from twisted.internet import reactor
class TestServer( unittest.TestCase ):
@classmethod
def setUpClass( self ):
threading.Thread( target = reactor.run, kwargs = { 'installSignalHandlers' : 0 } ).start()
services = []
self._local_service_identifier = HC.ServerServiceIdentifier( 'local file', HC.LOCAL_FILE )
self._file_service_identifier = HC.ServerServiceIdentifier( 'file service', HC.FILE_REPOSITORY )
self._tag_service_identifier = HC.ServerServiceIdentifier( 'tag service', HC.TAG_REPOSITORY )
permissions = [ HC.GET_DATA, HC.POST_DATA, HC.POST_PETITIONS, HC.RESOLVE_PETITIONS, HC.MANAGE_USERS, HC.GENERAL_ADMIN, HC.EDIT_SERVICES ]
account_id = 1
account_type = HC.AccountType( 'account', permissions, ( None, None ) )
created = HC.GetNow() - 100000
expires = None
used_data = ( 0, 0 )
self._account = HC.Account( account_id, account_type, created, expires, used_data )
self._access_key = os.urandom( 32 )
self._file_hash = os.urandom( 32 )
def TWISTEDSetup():
reactor.listenTCP( HC.DEFAULT_SERVER_ADMIN_PORT, HydrusServer.HydrusServiceAdmin( HC.SERVER_ADMIN_IDENTIFIER, 'hello' ) )
reactor.listenTCP( HC.DEFAULT_LOCAL_FILE_PORT, HydrusServer.HydrusServiceLocal( self._local_service_identifier, 'hello' ) )
reactor.listenTCP( HC.DEFAULT_SERVICE_PORT, HydrusServer.HydrusServiceRepositoryFile( self._file_service_identifier, 'hello' ) )
reactor.listenTCP( HC.DEFAULT_SERVICE_PORT + 1, HydrusServer.HydrusServiceRepositoryTag( self._tag_service_identifier, 'hello' ) )
reactor.callFromThread( TWISTEDSetup )
time.sleep( 1 )
@classmethod
def tearDownClass( self ):
reactor.callFromThread( reactor.stop )
def _test_basics( self, host, port ):
connection = httplib.HTTPConnection( host, port, timeout = 10 )
#
connection.request( 'GET', '/' )
response = connection.getresponse()
data = response.read()
p1 = data == HydrusServerResources.CLIENT_ROOT_MESSAGE
p2 = data == HydrusServerResources.ROOT_MESSAGE_BEGIN + 'hello' + HydrusServerResources.ROOT_MESSAGE_END
self.assertTrue( p1 or p2 )
#
with open( HC.STATIC_DIR + os.path.sep + 'hydrus.ico', 'rb' ) as f: favicon = f.read()
connection.request( 'GET', '/favicon.ico' )
response = connection.getresponse()
data = response.read()
self.assertEqual( data, favicon )
def _test_local_file( self, host, port ):
connection = httplib.HTTPConnection( host, port, timeout = 10 )
#
path = CC.GetExpectedFilePath( self._file_hash, HC.IMAGE_JPEG )
with open( path, 'wb' ) as f: f.write( 'file' )
connection.request( 'GET', '/file?hash=' + self._file_hash.encode( 'hex' ) )
response = connection.getresponse()
data = response.read()
self.assertEqual( data, 'file' )
try: os.remove( path )
except: pass
#
path = CC.GetExpectedThumbnailPath( self._file_hash )
with open( path, 'wb' ) as f: f.write( 'thumb' )
connection.request( 'GET', '/thumbnail?hash=' + self._file_hash.encode( 'hex' ) )
response = connection.getresponse()
data = response.read()
self.assertEqual( data, 'thumb' )
try: os.remove( path )
except: pass
def _test_file_repo( self, host, port ):
# set up connection
service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.FILE_REPOSITORY, 'service' )
credentials = CC.Credentials( host, port, self._access_key )
connection = CC.ConnectionToService( service_identifier, credentials )
file_connection = httplib.HTTPConnection( host, port, timeout = 10 )
# file
path = SC.GetExpectedPath( 'file', self._file_hash )
with open( path, 'wb' ) as f: f.write( 'file' )
response = connection.Get( 'file', hash = self._file_hash.encode( 'hex' ) )
self.assertEqual( response, 'file' )
try: os.remove( path )
except: pass
path = HC.STATIC_DIR + os.path.sep + 'hydrus.png'
with open( path, 'rb' ) as f: file = f.read()
connection.Post( 'file', file = file )
written = HC.app.GetWrite( 'file' )
[ ( args, kwargs ) ] = written
( written_service_identifier, written_account, written_file_dict ) = args
self.assertEqual( written_file_dict[ 'hash' ], '\xadm5\x99\xa6\xc4\x89\xa5u\xeb\x19\xc0&\xfa\xce\x97\xa9\xcdey\xe7G(\xb0\xce\x94\xa6\x01\xd22\xf3\xc3' )
self.assertEqual( written_file_dict[ 'ip' ], '127.0.0.1' )
self.assertEqual( written_file_dict[ 'height' ], 200 )
self.assertEqual( written_file_dict[ 'width' ], 200 )
self.assertEqual( written_file_dict[ 'mime' ], 2 )
self.assertEqual( written_file_dict[ 'size' ], 5270 )
# ip
( ip, timestamp ) = ( '94.45.87.123', HC.GetNow() - 100000 )
HC.app.SetRead( 'ip', ( ip, timestamp ) )
response = connection.Get( 'ip', hash = self._file_hash.encode( 'hex' ) )
self.assertEqual( response[ 'ip' ], ip )
self.assertEqual( response[ 'timestamp' ], timestamp )
# thumbnail
path = SC.GetExpectedPath( 'thumbnail', self._file_hash )
with open( path, 'wb' ) as f: f.write( 'thumb' )
response = connection.Get( 'thumbnail', hash = self._file_hash.encode( 'hex' ) )
self.assertEqual( response, 'thumb' )
try: os.remove( path )
except: pass
def _test_repo( self, host, port, service_type ):
# set up connection
service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), service_type, 'service' )
credentials = CC.Credentials( host, port, self._access_key )
connection = CC.ConnectionToService( service_identifier, credentials )
# news
news = 'this is the news'
connection.Post( 'news', news = news )
written = HC.app.GetWrite( 'news' )
[ ( args, kwargs ) ] = written
( written_service_identifier, written_news ) = args
self.assertEqual( news, written_news )
# num_petitions
num_petitions = 23
HC.app.SetRead( 'num_petitions', num_petitions )
response = connection.Get( 'num_petitions' )
self.assertEqual( response[ 'num_petitions' ], num_petitions )
# petition
petition = 'petition'
HC.app.SetRead( 'petition', petition )
response = connection.Get( 'petition' )
self.assertEqual( response[ 'petition' ], petition )
# update
update = 'update'
update_key = os.urandom( 32 )
path = SC.GetExpectedPath( 'update', update_key )
with open( path, 'wb' ) as f: f.write( update )
HC.app.SetRead( 'update_key', update_key )
response = connection.Get( 'update', begin = 100 )
self.assertEqual( response, update )
try: os.remove( path )
except: pass
connection.Post( 'update', update = update )
written = HC.app.GetWrite( 'update' )
[ ( args, kwargs ) ] = written
( written_service_identifier, written_account, written_update ) = args
self.assertEqual( update, written_update )
def _test_restricted( self, host, port, service_type ):
# access_key
registration_key = os.urandom( 32 )
HC.app.SetRead( 'access_key', self._access_key )
connection = HC.get_connection( host = host, port = port )
headers = {}
headers[ 'Hydrus-Key' ] = registration_key.encode( 'hex' )
response = connection.request( 'GET', '/access_key', headers = headers )
self.assertEqual( response[ 'access_key' ], self._access_key )
# set up connection
service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), service_type, 'service' )
credentials = CC.Credentials( host, port, self._access_key )
connection = CC.ConnectionToService( service_identifier, credentials )
# set up session
last_error = 0
account = self._account
service_for_session_manager = CC.ServiceRemoteRestricted( service_identifier, credentials, last_error, account )
HC.app.SetRead( 'service', service_for_session_manager )
HC.app.SetRead( 'account', self._account )
# account
response = connection.Get( 'account' )
self.assertEqual( repr( response[ 'account' ] ), repr( self._account ) )
# account_info
account_info = { 'message' : 'hello' }
HC.app.SetRead( 'account_info', account_info )
response = connection.Get( 'account_info', subject_account_id = 1 )
self.assertEqual( response[ 'account_info' ], account_info )
response = connection.Get( 'account_info', subject_access_key = os.urandom( 32 ).encode( 'hex' ) )
self.assertEqual( response[ 'account_info' ], account_info )
response = connection.Get( 'account_info', subject_hash = os.urandom( 32 ).encode( 'hex' ) )
self.assertEqual( response[ 'account_info' ], account_info )
response = connection.Get( 'account_info', subject_hash = os.urandom( 32 ).encode( 'hex' ), subject_tag = 'hello'.encode( 'hex' ) )
self.assertEqual( response[ 'account_info' ], account_info )
# account_types
account_types = { 'message' : 'hello' }
HC.app.SetRead( 'account_types', account_types )
response = connection.Get( 'account_types' )
self.assertEqual( response[ 'account_types' ], account_types )
edit_log = 'blah'
connection.Post( 'account_types', edit_log = edit_log )
written = HC.app.GetWrite( 'account_types' )
[ ( args, kwargs ) ] = written
( written_service_identifier, written_edit_log ) = args
self.assertEqual( edit_log, written_edit_log )
# registration_keys
registration_key = os.urandom( 32 )
HC.app.SetRead( 'registration_keys', [ registration_key ] )
response = connection.Get( 'registration_keys', num = 1, title = 'blah' )
self.assertEqual( response[ 'registration_keys' ], [ registration_key ] )
response = connection.Get( 'registration_keys', num = 1, title = 'blah', expiration = 100 )
self.assertEqual( response[ 'registration_keys' ], [ registration_key ] )
# stats
stats = { 'message' : 'hello' }
HC.app.SetRead( 'stats', stats )
response = connection.Get( 'stats' )
self.assertEqual( response[ 'stats' ], stats )
def _test_server_admin( self, host, port ):
# set up init connection
service_identifier = HC.ClientServiceIdentifier( os.urandom( 32 ), HC.SERVER_ADMIN, 'server admin' )
credentials = CC.Credentials( host, port )
connection = CC.ConnectionToService( service_identifier, credentials )
# init
access_key = os.urandom( 32 )
HC.app.SetRead( 'init', access_key )
response = connection.Get( 'init' )
self.assertEqual( response[ 'access_key' ], access_key )
# set up connection
credentials = CC.Credentials( host, port, self._access_key )
connection = CC.ConnectionToService( service_identifier, credentials )
# backup
response = connection.Post( 'backup' )
# services
services = { 'message' : 'hello' }
HC.app.SetRead( 'services', services )
response = connection.Get( 'services' )
self.assertEqual( response[ 'services_info' ], services )
edit_log = 'blah'
connection.Post( 'services', edit_log = edit_log )
written = HC.app.GetWrite( 'services' )
[ ( args, kwargs ) ] = written
( written_service_identifier, written_edit_log ) = args
self.assertEqual( edit_log, written_edit_log )
def _test_tag_repo( self, host, port ):
pass
def test_local_service( self ):
host = '127.0.0.1'
port = HC.DEFAULT_LOCAL_FILE_PORT
self._test_basics( host, port )
self._test_local_file( host, port )
def test_repository_file( self ):
host = '127.0.0.1'
port = HC.DEFAULT_SERVICE_PORT
self._test_basics( host, port )
self._test_restricted( host, port, HC.FILE_REPOSITORY )
self._test_repo( host, port, HC.FILE_REPOSITORY )
self._test_file_repo( host, port )
def test_repository_tag( self ):
host = '127.0.0.1'
port = HC.DEFAULT_SERVICE_PORT + 1
self._test_basics( host, port )
self._test_restricted( host, port, HC.TAG_REPOSITORY )
self._test_repo( host, port, HC.TAG_REPOSITORY )
self._test_tag_repo( host, port )
def test_server_admin( self ):
host = '127.0.0.1'
port = HC.DEFAULT_SERVER_ADMIN_PORT
self._test_basics( host, port )
self._test_restricted( host, port, HC.SERVER_ADMIN )
self._test_server_admin( host, port )