def reconstruct_as_pointer(path, index): """ Reconstruct a block by reassembling a codeword it was part of and plucking it from the result. Args: path(str): Path to the file the block belongs to index(int): Index of the block Returns: bytes: The constructed block Raises: ValueError: If path is not a string or is empty or if the index is negative RuntimeError: If the block has never been pointed at """ if not isinstance(path, str) or not path: raise ValueError("path argument must be a non empty string") if not isinstance(index, int) or index < 0: raise ValueError("index argument must be an integer greater or equal to 0") metablock = get_block_metadata(path, index) documents = find_pointing_documents(path, index) if not documents: raise RuntimeError("Could not find any pointing document") with open(os.path.join(os.path.dirname(__file__), "..", "dispatcher.json"), "r") as handle: entanglement_configuration = json.load(handle)["entanglement"]["configuration"] source_blocks = entanglement_configuration["s"] pointer_blocks = entanglement_configuration["t"] offset = source_blocks + pointer_blocks files = Files() for document in documents: index_to_reconstruct = get_position_in_codeword(document, metablock) coder_client = CoderClient() reconstructed_block = coder_client.reconstruct(document.path, [index_to_reconstruct])[index_to_reconstruct].data elements = split_strip_header(reconstructed_block) fragment_header = elements[2] metadata = files.get(path) fragment_header.metadata.index = offset + index fragment_size = int(math.ceil(metadata.original_size / float(source_blocks))) if (fragment_size % 2) == 1: fragment_size += 1 fragment_header.metadata.size = fragment_size fragment_header.metadata.orig_data_size = fragment_size * (offset) brand_new = json.dumps(metadata.entangling_blocks) + HEADER_DELIMITER + \ str(metadata.original_size) + HEADER_DELIMITER + \ fragment_header.pack() + \ get_fragment(reconstructed_block) brand_new = brand_new[:metablock.size] computed_checksum = hashlib.sha256(brand_new).digest() if computed_checksum == metablock.checksum: return brand_new raise RuntimeError("Could not reconstruct {:s} from pointing documents".format(metablock.key))
def test_files_get(monkeypatch): with mock.patch("socket.gethostbyname", return_value="127.0.0.1"): files = Files() def mock_pipeline_get(path): return [{ "path": "path", "original_size": "0", "creation_date": "2017-01-01 00:00:00.42", "blocks": "", "providers": "", "block_type": BlockType.DATA.name, "entangling_blocks": "[]" }] monkeypatch.setattr(FakeRedisPipeline, "execute", mock_pipeline_get) monkeypatch.setattr(files.redis, "pipeline", get_me_a_fake_redis_pipeline) metadata = files.get("path") assert metadata.path == "path"
def test_files_get_raises_keyerror_when_path_not_in_files(monkeypatch): with mock.patch("socket.gethostbyname", return_value="127.0.0.1"): files = Files() monkeypatch.setattr(files.redis, "pipeline", get_me_a_fake_redis_pipeline) with pytest.raises(KeyError, match="path NonExistingKey not found"): files.get("NonExistingKey")
def test_files_get_raises_valueerror_when_path_is_empty(): with mock.patch("socket.gethostbyname", return_value="127.0.0.1"): files = Files() with pytest.raises(ValueError, match="path argument must be a valid non-empty string"): files.get("")