def test_release_free_resource(): """ TestCase Senario: trying to send a release request for a free resource which is not allowed so the wrong message response is expected. """ #targeted resource and client_address resource_name = 'resourceX' client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s and send the release request for resourceX s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall('release resourceX') data = s.recv(1024) #expecting error message as a response assert data == 'resource is already free.' # the status of the resource was free and still free assert client_lock.check_status() == 'free' #close the socket client s.close()
def test_lock_resourceX_then_close_connection(): """ TestCase Senario: the client try to lock the resourceX then this client close the connection. when the connection between the client and the server is down, the server should release the lock on the resourceX automatically """ #targeted resource and client_address resource_name = 'resourceX' resource_id = get_resource_id_by_name(resource_name)[0] client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s and send the request access to resourceX s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) if status == 'free': s.sendall('lock resourceX') data = s.recv(1024) # make sure the access is granted assert data == 'You have an exclusive access to resource resourceX' assert client_lock.check_status() == 'busy' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 1 assert operations[0][0] == client_address assert operations[0][2] == "lock" # the client terminate the connection s.close() #delete operations delete_operation_by_resource_id(resource_id) elif status == 'busy': s.sendall('lock resourceX') data = s.recv(1024) # make sure the resourceX is busy assert data == 'required resource is busy now, you have to wait a while' assert client_lock.check_status() == 'busy' # the client terminate the connection s.close() # sleep for 5 seconds to make sure the server cleaning up is done time.sleep(5) # make sure the server make resourceX free after the client terminates the connection assert client_lock.check_status() == 'free'
def test_release_locked_resource_by_different_client(): """ TestCase Senario: at first lock the resourceX by the client 192.168.0.1 then ask the server as the client 127.0.0.1 to lock or release the resourceX """ #targeted resource and client_address resource_name = 'resourceX' client_address1 = '127.0.0.1' client_address2 = '192.168.0.1' client_lock = Lock(resource_name, client_address1) status = client_lock.check_status() #initiate socket s and send the request access to resourceX s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) if status == 'free': # lock the resourceX by the client '192.168.0.1' update_resource_status(resource_name, 'busy', client_address2) #make sure the resourceX status is busy assert client_lock.check_status() == 'busy' s.sendall('lock resourceX') data = s.recv(1024) #make sure the resourceX status is busy assert data == 'required resource is busy now, you have to wait a while' assert client_lock.check_status() == 'busy' s.sendall('release resourceX') data = s.recv(1024) #make sure the resourceX status is busy and the release failed because the ip is different assert data == 'it is not allowed to release someone else resource' assert client_lock.check_status() == 'busy' update_resource_status(resource_name, 'free', client_address2) #make sure the resourceX status is free assert client_lock.check_status() == 'free' #close the socket client s.close()
def clientthread(conn, client_address): #infinite loop so that function do not terminate and thread do not end. while True: #Receiving from client try: data = conn.recv(RECV_BUFFER) #release or lock resource_name except: #release all locked resources for the client address client_lock = Lock("", client_address) client_lock.release_by_client_address() break else: #split the message Received to get the command and the resource name tmp = data.split() # check if the message Received follows the correct format if tmp is not None and len(tmp) == 2 and (tmp[0] == "release" or tmp[0] == "lock"): # operation has to be lock or release operation = tmp[0] resource_name = tmp[1] #targeted resource name and status client_lock = Lock(resource_name, client_address) resource_status = client_lock.check_status() if not data: break elif resource_status is None: # targeted resource is not listed in the database reply = "required resource is not listed" elif operation == 'lock' and resource_status == "free": # you gain access to the resource reply = "You have an exclusive access to resource " + resource_name client_lock.acquire() elif operation == 'lock' and resource_status == "busy": # the resource is busy, you will wait TIMEOUT secs and retry time.sleep(TIMEOUT) # checking the resource status again after TIMEOUT resource_status_new = client_lock.check_status() if resource_status_new == "busy": # it is still busy, try again later reply = "required resource is busy now, you have to wait a while" else: #it's free now, you will gain access reply = "You have an exclusive access to resource " + resource_name client_lock.acquire() elif operation == 'release': if resource_status == "free": #trying to release a free resource, not allowed reply = "resource is already free." #checking if the client who request release is the same client who lock it in the first place elif client_address in client_lock.get_client_address(): reply = "lock released from resource " + resource_name client_lock.release() else: # trying to release someone else's resource, not allowed reply = 'it is not allowed to release someone else resource' else: #the message Received does not follow the correct format so send an error message reply = "wrong message, you must send release or lock as the first word then space then the resource_name" #send the message to the client conn.sendall(reply) #came out of loop and close the connection conn.close()
def test_operations(): """ TestCase Senario: the main purpose of this test case is to make sure that the insertion into operations table works good by trying to lock resourceZ then check the database then release the lock on resourceZ then check the database again """ #targeted resource and client_address resource_name = 'resourceZ' resource_id = get_resource_id_by_name(resource_name)[0] #get number of operations stored in the database for the resourceZ initial_operations_length = len(get_operations_by_resource_id(resource_id)) client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s and send the request access to resourceZ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) if status == 'free': s.sendall('lock resourceZ') data = s.recv(1024) #make sure resourceZ is busy and you gain access assert data == 'You have an exclusive access to resource resourceZ' assert client_lock.check_status() == 'busy' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 1 + initial_operations_length assert operations[initial_operations_length][0] == client_address assert operations[initial_operations_length][2] == "lock" # sleep for 2 secs time.sleep(2) s.sendall('release resourceZ') data = s.recv(1024) # make sure the lock released and the resourceZ is free now assert data == 'lock released from resource resourceZ' assert client_lock.check_status() == 'free' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 2 + initial_operations_length assert operations[initial_operations_length][0] == client_address assert operations[initial_operations_length][2] == "lock" assert operations[1 + initial_operations_length][0] == client_address assert operations[1 + initial_operations_length][2] == "release" elif status == 'busy': s.sendall('lock resourceZ') data = s.recv(1024) assert data == 'required resource is busy now, you have to wait a while' assert client_lock.check_status() == 'busy' #close the socket client s.close()
def test_lock_resourceX_then_unlock(): """ TestCase Senario: the client try to lock the resourceX then release the lock on the resourceX """ #targeted resource and client_address resource_name = 'resourceX' resource_id = get_resource_id_by_name(resource_name)[0] client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s and send the request access to resourceX s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) if status == 'free': s.sendall('lock resourceX') data = s.recv(1024) # make sure the access is granted assert data == 'You have an exclusive access to resource resourceX' assert client_lock.check_status() == 'busy' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 1 assert operations[0][0] == client_address assert operations[0][2] == "lock" # sleep for 5 seconds time.sleep(5) # release the lock on resourceX s.sendall('release resourceX') data = s.recv(1024) # make sure the release done assert data == 'lock released from resource resourceX' assert client_lock.check_status() == 'free' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 2 assert operations[0][0] == client_address assert operations[0][2] == "lock" assert operations[1][0] == client_address assert operations[1][2] == "release" elif status == 'busy': s.sendall('lock resourceX') data = s.recv(1024) assert data == 'required resource is busy now, you have to wait a while' assert client_lock.check_status() == 'busy' #delete operations delete_operation_by_resource_id(resource_id) #close the socket client s.close()
def test_access_locked_resource_then_unlock_before_timeout(): """ TestCase Senario: there are 2 sockets s1 and s2. s1 lock resourceX then s2 tries to access resourceX but he couldn't so s2 have to wait TIMEOUT to retry but before the TIMEOUT ends, s1 release the lock so resourceX become free when TIMEOUT ends and s2 retries to access resourceX then it gains exclusive access to resourceX. """ #targeted resource and client_address resource_name = 'resourceX' resource_id = get_resource_id_by_name(resource_name)[0] client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s1 and lock resourceX s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s1.connect((HOST, PORT)) if status == 'free': s1.sendall('lock resourceX') data = s1.recv(1024) #make sure the access is granted and resourceX is busy assert data == 'You have an exclusive access to resource resourceX' assert client_lock.check_status() == 'busy' # make sure this operation stored in the database #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 1 assert operations[0][0] == client_address assert operations[0][2] == "lock" # initiate socket s2 and try to lock resourceX but fails s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s2.connect((HOST, PORT)) s2.sendall('lock resourceX') assert client_lock.check_status() == 'busy' # before TIMEOUT ends, s1 release resourceX s1.sendall('release resourceX') data = s1.recv(1024) # make sure it released the resource successfully and resourceX is free assert data == 'lock released from resource resourceX' assert client_lock.check_status() == 'free' # make sure this operation stored in the database #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 2 assert operations[0][0] == client_address assert operations[0][2] == "lock" assert operations[1][0] == client_address assert operations[1][2] == "release" # close socket connection s1.close() # when s2 retries again, it locks resourceX and have an exclusive access data = s2.recv(1024) #make sure the access is granted and resourceX is busy assert data == 'You have an exclusive access to resource resourceX' assert client_lock.check_status() == 'busy' # make sure this operation stored in the database #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 3 assert operations[0][0] == client_address assert operations[0][2] == "lock" assert operations[1][0] == client_address assert operations[1][2] == "release" assert operations[2][0] == client_address assert operations[2][2] == "lock" # s2 release resourceX s2.sendall('release resourceX') data = s2.recv(1024) # make sure it released the resource successfully and resourceX is free assert data == 'lock released from resource resourceX' assert client_lock.check_status() == 'free' # make sure this operation stored in the database #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 4 assert operations[0][0] == client_address assert operations[0][2] == "lock" assert operations[1][0] == client_address assert operations[1][2] == "release" assert operations[2][0] == client_address assert operations[2][2] == "lock" assert operations[3][0] == client_address assert operations[3][2] == "release" #delete operations delete_operation_by_resource_id(resource_id) # close socket connection s2.close()
def test_access_locked_resource(): """ TestCase Senario: the first client s1 lock resourceX for a while. the second client s2 try to access resourceX which is locked by s1 so the request refused then s1 release the lock and set resourceX free """ #targeted resource and client_address resource_name = 'resourceX' resource_id = get_resource_id_by_name(resource_name)[0] client_address = '127.0.0.1' client_lock = Lock(resource_name, client_address) status = client_lock.check_status() #initiate socket s1 and send the request access to resourceX s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s1.connect((HOST, PORT)) if status == 'free': s1.sendall('lock resourceX') data = s1.recv(1024) # make sure the access is granted assert data == 'You have an exclusive access to resource resourceX' assert client_lock.check_status() == 'busy' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 1 assert operations[0][0] == client_address assert operations[0][2] == "lock" #initiate socket s2 and send the request access to resourceX s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s2.connect((HOST, PORT)) s2.sendall('lock resourceX') data = s2.recv(1024) # make sure the resourceX is busy and access is not granted assert data == 'required resource is busy now, you have to wait a while' assert client_lock.check_status() == 'busy' # the client terminate the connection s2.close() # s1 release the lock on resourceX s1.sendall('release resourceX') data = s1.recv(1024) # make sure the lock released and status is free now assert data == 'lock released from resource resourceX' assert client_lock.check_status() == 'free' # make sure this operation stored into the db #select operations # client_ip_address, operation_time, operation_type operations = get_operations_by_resource_id(resource_id) assert len(operations) == 2 assert operations[0][0] == client_address assert operations[0][2] == "lock" assert operations[1][0] == client_address assert operations[1][2] == "release" #delete operations delete_operation_by_resource_id(resource_id) # the client terminate the connection s1.close()