Skip to content

Commit

Permalink
fixed unit test
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Peterson <[email protected]>
  • Loading branch information
mattp-swirldslabs committed Jul 29, 2024
1 parent bb4c5af commit d20db18
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 27 deletions.
16 changes: 16 additions & 0 deletions server/src/main/java/com/hedera/block/server/ServiceStatus.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hedera.block.server;

import io.helidon.webserver.WebServer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.util.DaemonThreadFactory;
import io.helidon.webserver.WebServer;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,34 @@ public void write(final BlockItem blockItem) throws IOException {
}

final Path blockItemFilePath = calculateBlockItemPath();
for (int retries = 0;;retries++) {
for (int retries = 0; ; retries++) {
try {
write(blockItemFilePath, blockItem);
break;
} catch (IOException e) {

LOGGER.log(System.Logger.Level.ERROR, "Error writing the BlockItem protobuf to a file", e);
if (retries > 1) {
LOGGER.log(
System.Logger.Level.ERROR,
"Error writing the BlockItem protobuf to a file",
e);
if (retries > 0) {
// Attempt to remove the block
blockRemover.remove(blockNodeFileNameIndex);
blockRemover.remove(Long.parseLong(currentBlockDir.toString()));
throw e;
} else {
// Attempt to repair the permissions on the block path
// and the blockItem path
repairPermissions(blockNodeRootPath);
repairPermissions(calculateBlockPath());
LOGGER.log(System.Logger.Level.INFO, "Retrying to write the BlockItem protobuf to a file");
LOGGER.log(
System.Logger.Level.INFO,
"Retrying to write the BlockItem protobuf to a file");
}
}
}
}

private void write(final Path blockItemFilePath, final BlockItem blockItem) throws IOException {
void write(final Path blockItemFilePath, final BlockItem blockItem) throws IOException {
try (FileOutputStream fos = new FileOutputStream(blockItemFilePath.toString())) {
blockItem.writeTo(fos);
LOGGER.log(
Expand Down Expand Up @@ -133,7 +139,7 @@ private void resetState(final BlockItem blockItem) throws IOException {
blockNodeFileNameIndex = 0;
}

private void repairPermissions(final Path path) throws IOException{
private void repairPermissions(final Path path) throws IOException {
final boolean isReadable = Files.isReadable(path);
final boolean isWritable = Files.isWritable(path);
if (!isWritable || !isReadable) {
Expand All @@ -157,7 +163,7 @@ private void repairPermissions(final Path path) throws IOException{
} catch (IOException e) {
LOGGER.log(
System.Logger.Level.ERROR,
"Error setting permissions on the block node root directory",
"Error setting permissions on the path: " + path,
e);
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.hedera.block.server.data.ObjectEvent;
import com.hedera.block.server.mediator.StreamMediator;
import io.grpc.stub.StreamObserver;
import io.helidon.webserver.WebServer;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class BlockAsDirectoryTest {
Expand Down Expand Up @@ -192,18 +194,19 @@ public void testRemoveBlockWritePerms() throws IOException {
}

@Test
@Disabled
public void testRemoveBlockItemWritePerms() throws IOException {

final List<BlockItem> blockItems = PersistTestUtils.generateBlockItems(1);
final BlockWriter<BlockItem> blockWriter = new BlockAsDirWriter(JUNIT, testConfig);

// Writing the header BlockItem will create the block directory.
blockWriter.write(blockItems.get(0));
final BlockRemover blockRemover =
new BlockAsDirRemover(
Path.of(testConfig.get(JUNIT).asString().get()), Util.defaultPerms);
final BlockWriter<BlockItem> blockWriter =
new TestIOExceptionBlockAsDirWriter(
JUNIT, testConfig, blockRemover, Util.defaultPerms, 0);

// Change the permissions on the block node root directory
removeBlockWritePerms(1, testConfig);
assertThrows(IOException.class, () -> blockWriter.write(blockItems.get(1)));
// TestBlockAsDirWriter overrides the write method to always
// throw an IOException
assertThrows(IOException.class, () -> blockWriter.write(blockItems.get(0)));
}

@Test
Expand All @@ -215,21 +218,27 @@ public void testConstructorWithInvalidPath() {
}

@Test
@Disabled
public void testPartialBlockRemoval() throws IOException {
final List<BlockItem> blockItems = PersistTestUtils.generateBlockItems(1);
final BlockWriter<BlockItem> blockWriter = new BlockAsDirWriter(JUNIT, testConfig);
final BlockRemover blockRemover =
new BlockAsDirRemover(
Path.of(testConfig.get(JUNIT).asString().get()), Util.defaultPerms);
final BlockWriter<BlockItem> blockWriter =
new TestIOExceptionBlockAsDirWriter(
JUNIT, testConfig, blockRemover, Util.defaultPerms, 3);

// Write a few block items
blockWriter.write(blockItems.get(0));
blockWriter.write(blockItems.get(1));
blockWriter.write(blockItems.get(2));

// Remove write permissions from the block item
removeBlockWritePerms(1, testConfig);
// Attempt to write the next block should fail
assertThrows(IOException.class, () -> blockWriter.write(blockItems.get(3)));

// Attempt to read the block
assertThrows(IOException.class, () -> blockWriter.write(blockItems.get(4)));
// Verify the partially written block was removed
final BlockReader<Block> blockReader = new BlockAsDirReader(JUNIT, testConfig);
final Optional<Block> blockOpt = blockReader.read(1);
assertTrue(blockOpt.isEmpty());
}

private void removeBlockReadPerms(int blockNumber, final Config config) throws IOException {
Expand Down Expand Up @@ -264,4 +273,31 @@ private void removeBlockItemReadPerms(int blockNumber, int blockItem, Config con
final Path blockItemPath = blockPath.resolve(blockItem + BLOCK_FILE_EXTENSION);
Files.setPosixFilePermissions(blockItemPath, TestUtils.getNoRead().value());
}

static class TestIOExceptionBlockAsDirWriter extends BlockAsDirWriter {

final int blockItemsToAdmitBeforeFailure;
private int currentCount;

public TestIOExceptionBlockAsDirWriter(
final String key,
final Config config,
final BlockRemover blockRemover,
final FileAttribute<Set<PosixFilePermission>> filePerms,
final int blockItemsToAdmitBeforeFailure)
throws IOException {
super(key, config, blockRemover, filePerms);
this.blockItemsToAdmitBeforeFailure = blockItemsToAdmitBeforeFailure;
}

@Override
void write(final Path blockItemFilePath, final BlockItem blockItem) throws IOException {
if (currentCount < blockItemsToAdmitBeforeFailure) {
super.write(blockItemFilePath, blockItem);
currentCount++;
} else {
throw new IOException("Test exception");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import com.hedera.block.server.persistence.storage.BlockReader;
import com.hedera.block.server.persistence.storage.BlockWriter;
import io.grpc.stub.StreamObserver;
import io.helidon.webserver.WebServer;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
Expand Down Expand Up @@ -197,7 +196,10 @@ public void testItemAckBuilderExceptionTest()

ProducerBlockItemObserver producerBlockItemObserver =
new ProducerBlockItemObserver(
streamMediator, publishStreamResponseObserver, itemAckBuilder, serviceStatus);
streamMediator,
publishStreamResponseObserver,
itemAckBuilder,
serviceStatus);

when(streamMediator.isPublishing()).thenReturn(true);
when(itemAckBuilder.buildAck(any()))
Expand Down

0 comments on commit d20db18

Please sign in to comment.