def test_send_file(self): with open('/tmp/big_dummy_file_test', 'wb') as dummy_file: for i in range(100000): dummy_file.write(("%d%d%d" % (i, i, i)).encode('utf-8')) sha256 = hashlib.sha256() with open('/tmp/big_dummy_file_test', 'rb') as dummy_file: while True: data = dummy_file.read(2048) if not data: break sha256.update(data) original_hash = sha256.hexdigest() self.p = Process(target=file_sender, args=(self.barrier, TestBlockingSocketTransferer.TEST_PORT, '/tmp/big_dummy_file_test')) self.p.start() self.barrier.wait() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', TestBlockingSocketTransferer.TEST_PORT)) socket_transferer = BlockingSocketTransferer(sock) with open('/tmp/big_dummy_file_test_out', 'wb') as write_file: socket_transferer.receive_file_data(write_file) sha256 = hashlib.sha256() with open('/tmp/big_dummy_file_test_out', 'rb') as dummy_file: while True: data = dummy_file.read(2048) if not data: break sha256.update(data) self.assertEqual(sha256.hexdigest(), original_hash) os.remove('/tmp/big_dummy_file_test') os.remove('/tmp/big_dummy_file_test_out') socket_transferer.close()
def __call__(self) -> NoReturn: """ Code for running the handler in a new process The process works this way: 1. Connects to node sidecar asking for node_path compressed 2. If the backup is the same as previous checksum, writes a .SAME file 3. Downloads the file saving it in write file path 3.1. At start it writes an empty file named self.write_file_path but ending with .WIP 3.2. Starts saving the backup in a file located in self.write_file_path 3.3. When the backup is saved saves an empty file named self.write_file_path but ending with .CORRECT 3.4. Deletes the .WIP file 4. Seppuku """ NodeHandlerProcess.logger.debug( "Starting node handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path)) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((self.node_address, self.node_port)) socket_transferer = BlockingSocketTransferer(sock) socket_transferer.send_plain_text( json.dumps({ "checksum": self.previous_checksum, "path": self.node_path })) except Exception as e: NodeHandlerProcess.logger.exception( "Error while writing socket %s: %s" % (sock, e)) NodeHandlerProcess.logger.info( "Terminating handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path)) return msg = socket_transferer.receive_plain_text() if msg == "SAME": NodeHandlerProcess.logger.debug("The backup was the same") NodeHandlerProcess.logger.info( "Terminating handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path)) open(SAME_FILE_FORMAT % self.write_file_path, 'w').close() return if msg == "ABORT": NodeHandlerProcess.logger.error("Abort order sent from sidecar") NodeHandlerProcess.logger.info( "Terminating handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path)) return open(WIP_FILE_FORMAT % self.write_file_path, 'w').close() data_file = open(self.write_file_path, 'ab') try: socket_transferer.receive_file_data(data_file) NodeHandlerProcess.logger.debug("File data received") checksum = socket_transferer.receive_plain_text() except Exception as e: NodeHandlerProcess.logger.exception( "Error while reading socket %s: %s" % (sock, e)) NodeHandlerProcess.logger.info( "Terminating handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path)) return data_file.close() backup_file = BackupFile(self.write_file_path) if backup_file.get_hash() == checksum: NodeHandlerProcess.logger.debug("Backup checksum: %s" % checksum) else: NodeHandlerProcess.logger.error( "Error verifying checksum. Local: %s vs Server: %s" % (backup_file.get_hash(), checksum)) return open(CORRECT_FILE_FORMAT % self.write_file_path, 'w').close() os.remove(WIP_FILE_FORMAT % self.write_file_path) NodeHandlerProcess.logger.info( "Terminating handler for node %s:%d and path %s" % (self.node_address, self.node_port, self.node_path))