This is an automated email from the ASF dual-hosted git repository. mpochatkin pushed a commit to branch IGNITE-27201 in repository https://gitbox.apache.org/repos/asf/ignite-3.git
commit d3ba875c761a7b03ae85e8c9dccdb0e0ba3a244c Author: Pochatkin Mikhail <[email protected]> AuthorDate: Wed Jan 14 15:55:43 2026 +0300 Fix comments --- .../unit/ItNodeUnitInspectCommandTest.java | 387 +++++++++++++++++++++ ....java => ItNodeUnitInspectReplCommandTest.java} | 4 +- .../unit/ItNodeUnitStructureCommandTest.java | 209 ----------- ...StructureCall.java => NodeUnitInspectCall.java} | 10 +- ...ureCallInput.java => UnitInspectCallInput.java} | 24 +- .../cli/commands/node/unit/NodeUnitCommand.java | 2 +- ...ureCommand.java => NodeUnitInspectCommand.java} | 20 +- ...ommand.java => NodeUnitInspectReplCommand.java} | 20 +- .../commands/node/unit/NodeUnitReplCommand.java | 2 +- ...ureDecorator.java => UnitInspectDecorator.java} | 6 +- ...eCallTest.java => NodeUnitInspectCallTest.java} | 12 +- ...atorTest.java => UnitInspectDecoratorTest.java} | 67 ++-- 12 files changed, 464 insertions(+), 299 deletions(-) diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectCommandTest.java new file mode 100644 index 00000000000..9285f7d439d --- /dev/null +++ b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectCommandTest.java @@ -0,0 +1,387 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.internal.cli.commands.unit; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertAll; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.apache.ignite.internal.cli.CliIntegrationTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** Integration test for node unit inspect command. */ +public class ItNodeUnitInspectCommandTest extends CliIntegrationTest { + private static String testFile; + + private static Path testDirectory; + + private static Path recursiveDirectory; + + private static Path emptyFolderDirectory; + + @BeforeAll + static void beforeAll() throws IOException { + testDirectory = Files.createDirectory(WORK_DIR.resolve("test-structure")); + testFile = Files.createFile(testDirectory.resolve("test.txt")).toString(); + Files.createFile(testDirectory.resolve("test2.txt")); + Files.createFile(testDirectory.resolve("test3.txt")); + + // Files with special characters + Files.createFile(testDirectory.resolve("file with spaces.txt")); + Files.createFile(testDirectory.resolve("file-with-dashes.txt")); + Files.createFile(testDirectory.resolve("file_with_underscores.txt")); + Files.createFile(testDirectory.resolve("file.multiple.dots.txt")); + Files.createFile(testDirectory.resolve("file(with)parentheses.txt")); + Files.createFile(testDirectory.resolve("UPPERCASE.TXT")); + Files.createFile(testDirectory.resolve("MixedCase.Txt")); + + // Subdirectory with files + Path subDir = Files.createDirectory(testDirectory.resolve("sub-directory")); + Files.createFile(subDir.resolve("nested file.txt")); + Files.createFile(subDir.resolve("nested-file.txt")); + + // Deeply nested directory + Path deepDir = Files.createDirectories(testDirectory.resolve("level1").resolve("level2")); + Files.createFile(deepDir.resolve("deep file.txt")); + + // Setup for recursive deployment test with 3-level structure + recursiveDirectory = Files.createDirectory(WORK_DIR.resolve("test-recursive")); + + // Level 1 - root files with different naming conventions + Files.createFile(recursiveDirectory.resolve("root-config.xml")); + Files.createFile(recursiveDirectory.resolve("ROOT_README.md")); + Files.createFile(recursiveDirectory.resolve("root file.txt")); + + // Level 2 - subdirectories with different naming styles + Path srcDir = Files.createDirectory(recursiveDirectory.resolve("src")); + Files.createFile(srcDir.resolve("Main.java")); + Files.createFile(srcDir.resolve("Helper Class.java")); + Files.createFile(srcDir.resolve("util_functions.py")); + + Path resourcesDir = Files.createDirectory(recursiveDirectory.resolve("resources-dir")); + Files.createFile(resourcesDir.resolve("application.properties")); + Files.createFile(resourcesDir.resolve("messages_en.properties")); + + Path libDir = Files.createDirectory(recursiveDirectory.resolve("lib_folder")); + Files.createFile(libDir.resolve("dependency-1.0.jar")); + Files.createFile(libDir.resolve("NATIVE LIB.so")); + + // Level 3 - deeply nested with various cases + Path srcSubDir = Files.createDirectory(srcDir.resolve("com.example.app")); + Files.createFile(srcSubDir.resolve("Application.java")); + Files.createFile(srcSubDir.resolve("Service Impl.java")); + Files.createFile(srcSubDir.resolve("data_model.java")); + + Path resourceSubDir = Files.createDirectory(resourcesDir.resolve("i18n")); + Files.createFile(resourceSubDir.resolve("messages_ru.properties")); + Files.createFile(resourceSubDir.resolve("MESSAGES_DE.properties")); + + Path libSubDir = Files.createDirectory(libDir.resolve("native-libs")); + Files.createFile(libSubDir.resolve("lib_native.dll")); + Files.createFile(libSubDir.resolve("Native Lib.dylib")); + + // Setup for empty folder test + emptyFolderDirectory = Files.createDirectory(WORK_DIR.resolve("test-empty-folder")); + Files.createFile(emptyFolderDirectory.resolve("existing-file.txt")); + Files.createDirectory(emptyFolderDirectory.resolve("empty-folder")); + Path nonEmptyFolder = Files.createDirectory(emptyFolderDirectory.resolve("non-empty-folder")); + Files.createFile(nonEmptyFolder.resolve("file-in-folder.txt")); + Files.createDirectory(nonEmptyFolder.resolve("nested-empty-folder")); + } + + @Test + @DisplayName("Should display unit structure with tree view") + void structureTreeView() { + // Given deployed unit + String id = "test.structure.unit.1"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure + execute("node", "unit", "inspect", id, "--version", "1.0.0"); + + // Then + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + () -> assertOutputContains(id), + () -> assertOutputContains("test.txt"), + () -> assertOutputContains("test2.txt"), + () -> assertOutputContains("test3.txt"), + () -> assertOutputContains("file with spaces.txt"), + () -> assertOutputContains("file-with-dashes.txt"), + () -> assertOutputContains("file_with_underscores.txt"), + () -> assertOutputContains("file.multiple.dots.txt"), + () -> assertOutputContains("file(with)parentheses.txt"), + () -> assertOutputContains("UPPERCASE.TXT"), + () -> assertOutputContains("MixedCase.Txt"), + () -> assertOutputContains("sub-directory"), + () -> assertOutputContains("nested file.txt"), + () -> assertOutputContains("nested-file.txt"), + () -> assertOutputContains("level1"), + () -> assertOutputContains("level2"), + () -> assertOutputContains("deep file.txt"), + () -> assertOutputContains(" B)") // File size display + ); + } + + @Test + @DisplayName("Should display unit structure with plain view") + void structurePlainView() { + // Given deployed unit + String id = "test.structure.unit.2"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure with plain option + execute("node", "unit", "inspect", id, "--version", "1.0.0", "--plain"); + + // Then + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + () -> assertOutputContains("test.txt"), + () -> assertOutputContains("test2.txt"), + () -> assertOutputContains("test3.txt"), + () -> assertOutputContains("file with spaces.txt"), + () -> assertOutputContains("file-with-dashes.txt"), + () -> assertOutputContains("file_with_underscores.txt"), + () -> assertOutputContains("file.multiple.dots.txt"), + () -> assertOutputContains("file(with)parentheses.txt"), + () -> assertOutputContains("sub-directory"), + () -> assertOutputContains("level1"), + () -> assertOutputContains("level2") + ); + } + + @Test + @DisplayName("Should display error when version is missing") + void structureVersionIsMandatory() { + // When get structure without version + execute("node", "unit", "inspect", "test.unit.id"); + + // Then + assertAll( + () -> assertExitCodeIs(2), + () -> assertErrOutputContains("Missing required option: '--version=<version>'"), + this::assertOutputIsEmpty + ); + } + + @Test + @DisplayName("Should display error when unit does not exist") + void structureUnitNotFound() { + // When get structure of non-existing unit + execute("node", "unit", "inspect", "non.existing.unit", "--version", "1.0.0"); + + // Then + assertAll( + this::assertExitCodeIsError, + () -> assertErrOutputContains("not found") + ); + } + + @Test + @DisplayName("Should display structure from file deployment") + void structureFromFile() { + // Given deployed unit from file + String id = "test.structure.unit.3"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testFile); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure + execute("node", "unit", "inspect", id, "--version", "1.0.0"); + + // Then + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + () -> assertOutputContains(id), + () -> assertOutputContains("test.txt") + ); + } + + @Test + @DisplayName("Should display file sizes in human readable format") + void structureWithFileSizes() { + // Given deployed unit + String id = "test.structure.unit.4"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure + execute("node", "unit", "inspect", id, "--version", "1.0.0"); + + // Then verify file sizes are displayed + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + () -> assertOutputContains(" B)") // Size in bytes + ); + } + + @Test + @DisplayName("Should display 3-level structure with recursive deployment") + void structureWithRecursiveDeployment() { + // Given deployed unit with recursive option + String id = "test.recursive.unit.1"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", recursiveDirectory.toString(), "--recursive"); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure + execute("node", "unit", "inspect", id, "--version", "1.0.0"); + + // Then verify all 3 levels are present with different naming cases + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + // Level 1 - root files + () -> assertOutputContains("root-config.xml"), + () -> assertOutputContains("ROOT_README.md"), + () -> assertOutputContains("root file.txt"), + // Level 2 - directories and their files + () -> assertOutputContains("src"), + () -> assertOutputContains("Main.java"), + () -> assertOutputContains("Helper Class.java"), + () -> assertOutputContains("util_functions.py"), + () -> assertOutputContains("resources-dir"), + () -> assertOutputContains("application.properties"), + () -> assertOutputContains("messages_en.properties"), + () -> assertOutputContains("lib_folder"), + () -> assertOutputContains("dependency-1.0.jar"), + () -> assertOutputContains("NATIVE LIB.so"), + // Level 3 - deeply nested directories and files + () -> assertOutputContains("com.example.app"), + () -> assertOutputContains("Application.java"), + () -> assertOutputContains("Service Impl.java"), + () -> assertOutputContains("data_model.java"), + () -> assertOutputContains("i18n"), + () -> assertOutputContains("messages_ru.properties"), + () -> assertOutputContains("MESSAGES_DE.properties"), + () -> assertOutputContains("native-libs"), + () -> assertOutputContains("lib_native.dll"), + () -> assertOutputContains("Native Lib.dylib") + ); + } + + @Test + @DisplayName("Should display 3-level structure with recursive deployment in plain view") + void structureWithRecursiveDeploymentPlainView() { + // Given deployed unit with recursive option + String id = "test.recursive.unit.2"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", recursiveDirectory.toString(), "--recursive"); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure with plain view + execute("node", "unit", "inspect", id, "--version", "1.0.0", "--plain"); + + // Then verify nested paths are displayed correctly + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + // Verify nested paths include parent directories + () -> assertOutputContains("src/Main.java"), + () -> assertOutputContains("src/com.example.app/Application.java"), + () -> assertOutputContains("resources-dir/i18n/messages_ru.properties"), + () -> assertOutputContains("lib_folder/native-libs/lib_native.dll") + ); + } + + @Test + @DisplayName("Should display structure with empty folders using recursive deployment") + void structureWithEmptyFolders() { + // Given deployed unit with recursive option containing empty folders + String id = "test.empty.folder.unit.1"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", emptyFolderDirectory.toString(), "--recursive"); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure + execute("node", "unit", "inspect", id, "--version", "1.0.0"); + + // Then verify structure includes empty folders + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + // Root level file + () -> assertOutputContains("existing-file.txt"), + // Empty folder at root level + () -> assertOutputContains("empty-folder"), + // Non-empty folder with contents + () -> assertOutputContains("non-empty-folder"), + () -> assertOutputContains("file-in-folder.txt"), + // Nested empty folder + () -> assertOutputContains("nested-empty-folder") + ); + } + + @Test + @DisplayName("Should display structure with empty folders in plain view") + void structureWithEmptyFoldersPlainView() { + // Given deployed unit with recursive option containing empty folders + String id = "test.empty.folder.unit.2"; + execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", emptyFolderDirectory.toString(), "--recursive"); + + await().untilAsserted(() -> { + execute("cluster", "unit", "list", "--plain", id); + assertExitCodeIsZero(); + }); + + // When get structure with plain view + execute("node", "unit", "inspect", id, "--version", "1.0.0", "--plain"); + + // Then verify files are shown with correct paths + assertAll( + this::assertExitCodeIsZero, + this::assertErrOutputIsEmpty, + () -> assertOutputContains("existing-file.txt"), + () -> assertOutputContains("non-empty-folder/file-in-folder.txt") + ); + } +} diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureReplCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectReplCommandTest.java similarity index 88% rename from modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureReplCommandTest.java rename to modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectReplCommandTest.java index d74f6f87ed5..404a6315861 100644 --- a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureReplCommandTest.java +++ b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitInspectReplCommandTest.java @@ -20,8 +20,8 @@ package org.apache.ignite.internal.cli.commands.unit; import org.apache.ignite.internal.cli.commands.TopLevelCliReplCommand; import org.junit.jupiter.api.BeforeEach; -/** Integration test for node unit structure command in REPL mode. */ -class ItNodeUnitStructureReplCommandTest extends ItNodeUnitStructureCommandTest { +/** Integration test for node unit inspect command in REPL mode. */ +class ItNodeUnitInspectReplCommandTest extends ItNodeUnitInspectCommandTest { @BeforeEach void connect() { connect(NODE_URL); diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureCommandTest.java deleted file mode 100644 index 9642d4af31a..00000000000 --- a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/unit/ItNodeUnitStructureCommandTest.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.ignite.internal.cli.commands.unit; - -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.apache.ignite.internal.cli.CliIntegrationTest; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -/** Integration test for node unit structure command. */ -public class ItNodeUnitStructureCommandTest extends CliIntegrationTest { - private static String testFile; - - private static Path testDirectory; - - @BeforeAll - static void beforeAll() throws IOException { - testDirectory = Files.createDirectory(WORK_DIR.resolve("test-structure")); - testFile = Files.createFile(testDirectory.resolve("test.txt")).toString(); - Files.createFile(testDirectory.resolve("test2.txt")); - Files.createFile(testDirectory.resolve("test3.txt")); - - // Files with special characters - Files.createFile(testDirectory.resolve("file with spaces.txt")); - Files.createFile(testDirectory.resolve("file-with-dashes.txt")); - Files.createFile(testDirectory.resolve("file_with_underscores.txt")); - Files.createFile(testDirectory.resolve("file.multiple.dots.txt")); - Files.createFile(testDirectory.resolve("file(with)parentheses.txt")); - Files.createFile(testDirectory.resolve("UPPERCASE.TXT")); - Files.createFile(testDirectory.resolve("MixedCase.Txt")); - - // Subdirectory with files - Path subDir = Files.createDirectory(testDirectory.resolve("sub-directory")); - Files.createFile(subDir.resolve("nested file.txt")); - Files.createFile(subDir.resolve("nested-file.txt")); - - // Deeply nested directory - Path deepDir = Files.createDirectories(testDirectory.resolve("level1").resolve("level2")); - Files.createFile(deepDir.resolve("deep file.txt")); - } - - @Test - @DisplayName("Should display unit structure with tree view") - void structureTreeView() { - // Given deployed unit - String id = "test.structure.unit.1"; - execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); - - await().untilAsserted(() -> { - execute("cluster", "unit", "list", "--plain", id); - assertExitCodeIsZero(); - }); - - // When get structure - execute("node", "unit", "structure", id, "--version", "1.0.0"); - - // Then - assertAll( - this::assertExitCodeIsZero, - this::assertErrOutputIsEmpty, - () -> assertOutputContains(id), - () -> assertOutputContains("test.txt"), - () -> assertOutputContains("test2.txt"), - () -> assertOutputContains("test3.txt"), - () -> assertOutputContains("file with spaces.txt"), - () -> assertOutputContains("file-with-dashes.txt"), - () -> assertOutputContains("file_with_underscores.txt"), - () -> assertOutputContains("file.multiple.dots.txt"), - () -> assertOutputContains("file(with)parentheses.txt"), - () -> assertOutputContains("UPPERCASE.TXT"), - () -> assertOutputContains("MixedCase.Txt"), - () -> assertOutputContains("sub-directory"), - () -> assertOutputContains("nested file.txt"), - () -> assertOutputContains("nested-file.txt"), - () -> assertOutputContains("level1"), - () -> assertOutputContains("level2"), - () -> assertOutputContains("deep file.txt"), - () -> assertOutputContains(" B)") // File size display - ); - } - - @Test - @DisplayName("Should display unit structure with plain view") - void structurePlainView() { - // Given deployed unit - String id = "test.structure.unit.2"; - execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); - - await().untilAsserted(() -> { - execute("cluster", "unit", "list", "--plain", id); - assertExitCodeIsZero(); - }); - - // When get structure with plain option - execute("node", "unit", "structure", id, "--version", "1.0.0", "--plain"); - - // Then - assertAll( - this::assertExitCodeIsZero, - this::assertErrOutputIsEmpty, - () -> assertOutputContains("test.txt"), - () -> assertOutputContains("test2.txt"), - () -> assertOutputContains("test3.txt"), - () -> assertOutputContains("file with spaces.txt"), - () -> assertOutputContains("file-with-dashes.txt"), - () -> assertOutputContains("file_with_underscores.txt"), - () -> assertOutputContains("file.multiple.dots.txt"), - () -> assertOutputContains("file(with)parentheses.txt"), - () -> assertOutputContains("sub-directory"), - () -> assertOutputContains("level1"), - () -> assertOutputContains("level2") - ); - } - - @Test - @DisplayName("Should display error when version is missing") - void structureVersionIsMandatory() { - // When get structure without version - execute("node", "unit", "structure", "test.unit.id"); - - // Then - assertAll( - () -> assertExitCodeIs(2), - () -> assertErrOutputContains("Missing required option: '--version=<version>'"), - this::assertOutputIsEmpty - ); - } - - @Test - @DisplayName("Should display error when unit does not exist") - void structureUnitNotFound() { - // When get structure of non-existing unit - execute("node", "unit", "structure", "non.existing.unit", "--version", "1.0.0"); - - // Then - assertAll( - this::assertExitCodeIsError, - () -> assertErrOutputContains("not found") - ); - } - - @Test - @DisplayName("Should display structure from file deployment") - void structureFromFile() { - // Given deployed unit from file - String id = "test.structure.unit.3"; - execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testFile); - - await().untilAsserted(() -> { - execute("cluster", "unit", "list", "--plain", id); - assertExitCodeIsZero(); - }); - - // When get structure - execute("node", "unit", "structure", id, "--version", "1.0.0"); - - // Then - assertAll( - this::assertExitCodeIsZero, - this::assertErrOutputIsEmpty, - () -> assertOutputContains(id), - () -> assertOutputContains("test.txt") - ); - } - - @Test - @DisplayName("Should display file sizes in human readable format") - void structureWithFileSizes() { - // Given deployed unit - String id = "test.structure.unit.4"; - execute("cluster", "unit", "deploy", id, "--version", "1.0.0", "--path", testDirectory.toString()); - - await().untilAsserted(() -> { - execute("cluster", "unit", "list", "--plain", id); - assertExitCodeIsZero(); - }); - - // When get structure - execute("node", "unit", "structure", id, "--version", "1.0.0"); - - // Then verify file sizes are displayed - assertAll( - this::assertExitCodeIsZero, - this::assertErrOutputIsEmpty, - () -> assertOutputContains(" B)") // Size in bytes - ); - } -} diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCall.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCall.java similarity index 84% rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCall.java rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCall.java index 392a7afc67c..726f8b8314a 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCall.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCall.java @@ -18,7 +18,7 @@ package org.apache.ignite.internal.cli.call.node.unit; import jakarta.inject.Singleton; -import org.apache.ignite.internal.cli.call.unit.UnitStructureCallInput; +import org.apache.ignite.internal.cli.call.unit.UnitInspectCallInput; import org.apache.ignite.internal.cli.core.call.Call; import org.apache.ignite.internal.cli.core.call.CallOutput; import org.apache.ignite.internal.cli.core.call.DefaultCallOutput; @@ -28,17 +28,17 @@ import org.apache.ignite.rest.client.api.DeploymentApi; import org.apache.ignite.rest.client.invoker.ApiException; import org.apache.ignite.rest.client.model.UnitFolder; -/** Get unit structure on the node call. */ +/** Inspect unit on the node call. */ @Singleton -public class NodeUnitStructureCall implements Call<UnitStructureCallInput, UnitFolder> { +public class NodeUnitInspectCall implements Call<UnitInspectCallInput, UnitFolder> { private final ApiClientFactory clientFactory; - public NodeUnitStructureCall(ApiClientFactory clientFactory) { + public NodeUnitInspectCall(ApiClientFactory clientFactory) { this.clientFactory = clientFactory; } @Override - public CallOutput<UnitFolder> execute(UnitStructureCallInput input) { + public CallOutput<UnitFolder> execute(UnitInspectCallInput input) { try { DeploymentApi api = new DeploymentApi(clientFactory.getClient(input.url())); UnitFolder structure = api.unitContent(input.unitId(), input.version()); diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitStructureCallInput.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitInspectCallInput.java similarity index 69% rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitStructureCallInput.java rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitInspectCallInput.java index e5e4c7e0260..63abbb069f0 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitStructureCallInput.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/unit/UnitInspectCallInput.java @@ -19,8 +19,8 @@ package org.apache.ignite.internal.cli.call.unit; import org.apache.ignite.internal.cli.core.call.CallInput; -/** Input for unit structure call. */ -public class UnitStructureCallInput implements CallInput { +/** Input for unit inspect call. */ +public class UnitInspectCallInput implements CallInput { private final String unitId; @@ -28,14 +28,14 @@ public class UnitStructureCallInput implements CallInput { private final String url; - private UnitStructureCallInput(String unitId, String version, String url) { + private UnitInspectCallInput(String unitId, String version, String url) { this.unitId = unitId; this.version = version; this.url = url; } - public static UnitStructureCallInputBuilder builder() { - return new UnitStructureCallInputBuilder(); + public static UnitInspectCallInputBuilder builder() { + return new UnitInspectCallInputBuilder(); } public String unitId() { @@ -50,31 +50,31 @@ public class UnitStructureCallInput implements CallInput { return url; } - /** Builder for {@link UnitStructureCallInput}. */ - public static class UnitStructureCallInputBuilder { + /** Builder for {@link UnitInspectCallInput}. */ + public static class UnitInspectCallInputBuilder { private String unitId; private String version; private String url; - public UnitStructureCallInputBuilder unitId(String unitId) { + public UnitInspectCallInputBuilder unitId(String unitId) { this.unitId = unitId; return this; } - public UnitStructureCallInputBuilder version(String version) { + public UnitInspectCallInputBuilder version(String version) { this.version = version; return this; } - public UnitStructureCallInputBuilder url(String url) { + public UnitInspectCallInputBuilder url(String url) { this.url = url; return this; } - public UnitStructureCallInput build() { - return new UnitStructureCallInput(unitId, version, url); + public UnitInspectCallInput build() { + return new UnitInspectCallInput(unitId, version, url); } } } diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitCommand.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitCommand.java index 96d1076ed8d..f8a01f49d63 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitCommand.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitCommand.java @@ -21,6 +21,6 @@ import org.apache.ignite.internal.cli.commands.BaseCommand; import picocli.CommandLine.Command; /** Manages deployment units on node level. */ -@Command(name = "unit", subcommands = {NodeUnitListCommand.class, NodeUnitStructureCommand.class}, description = "Manages deployment units") +@Command(name = "unit", subcommands = {NodeUnitListCommand.class, NodeUnitInspectCommand.class}, description = "Manages deployment units") public class NodeUnitCommand extends BaseCommand { } diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureCommand.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectCommand.java similarity index 78% rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureCommand.java rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectCommand.java index 91491bc9c3f..8c474073b7d 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureCommand.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectCommand.java @@ -24,21 +24,21 @@ import static org.apache.ignite.internal.cli.commands.Options.Constants.VERSION_ import jakarta.inject.Inject; import java.util.concurrent.Callable; -import org.apache.ignite.internal.cli.call.node.unit.NodeUnitStructureCall; -import org.apache.ignite.internal.cli.call.unit.UnitStructureCallInput; +import org.apache.ignite.internal.cli.call.node.unit.NodeUnitInspectCall; +import org.apache.ignite.internal.cli.call.unit.UnitInspectCallInput; import org.apache.ignite.internal.cli.commands.BaseCommand; import org.apache.ignite.internal.cli.commands.node.NodeUrlProfileMixin; import org.apache.ignite.internal.cli.core.call.CallExecutionPipeline; import org.apache.ignite.internal.cli.core.exception.handler.ClusterNotInitializedExceptionHandler; -import org.apache.ignite.internal.cli.decorators.UnitStructureDecorator; +import org.apache.ignite.internal.cli.decorators.UnitInspectDecorator; import picocli.CommandLine.Command; import picocli.CommandLine.Mixin; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -/** Command to show deployment unit structure. */ -@Command(name = "structure", description = "Shows the structure of a deployed unit") -public class NodeUnitStructureCommand extends BaseCommand implements Callable<Integer> { +/** Command to inspect deployment unit. */ +@Command(name = "inspect", description = "Inspects the structure of a deployed unit") +public class NodeUnitInspectCommand extends BaseCommand implements Callable<Integer> { @Parameters(index = "0", description = "Deployment unit id") private String unitId; @@ -53,18 +53,18 @@ public class NodeUnitStructureCommand extends BaseCommand implements Callable<In private boolean plain; @Inject - private NodeUnitStructureCall call; + private NodeUnitInspectCall call; @Override public Integer call() throws Exception { return runPipeline(CallExecutionPipeline.builder(call) - .inputProvider(() -> UnitStructureCallInput.builder() + .inputProvider(() -> UnitInspectCallInput.builder() .unitId(unitId) .version(version) .url(nodeUrl.getNodeUrl()) .build()) - .decorator(new UnitStructureDecorator(plain)) - .exceptionHandler(ClusterNotInitializedExceptionHandler.createHandler("Cannot get unit structure")) + .decorator(new UnitInspectDecorator(plain)) + .exceptionHandler(ClusterNotInitializedExceptionHandler.createHandler("Cannot inspect unit")) ); } } diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectReplCommand.java similarity index 79% rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureReplCommand.java rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectReplCommand.java index c5c46ca724c..b0be2291d7e 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitStructureReplCommand.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitInspectReplCommand.java @@ -23,22 +23,22 @@ import static org.apache.ignite.internal.cli.commands.Options.Constants.UNIT_VER import static org.apache.ignite.internal.cli.commands.Options.Constants.VERSION_OPTION; import jakarta.inject.Inject; -import org.apache.ignite.internal.cli.call.node.unit.NodeUnitStructureCall; -import org.apache.ignite.internal.cli.call.unit.UnitStructureCallInput; +import org.apache.ignite.internal.cli.call.node.unit.NodeUnitInspectCall; +import org.apache.ignite.internal.cli.call.unit.UnitInspectCallInput; import org.apache.ignite.internal.cli.commands.BaseCommand; import org.apache.ignite.internal.cli.commands.node.NodeUrlMixin; import org.apache.ignite.internal.cli.commands.questions.ConnectToClusterQuestion; import org.apache.ignite.internal.cli.core.exception.handler.ClusterNotInitializedExceptionHandler; import org.apache.ignite.internal.cli.core.flow.builder.Flows; -import org.apache.ignite.internal.cli.decorators.UnitStructureDecorator; +import org.apache.ignite.internal.cli.decorators.UnitInspectDecorator; import picocli.CommandLine.Command; import picocli.CommandLine.Mixin; import picocli.CommandLine.Option; import picocli.CommandLine.Parameters; -/** Command to show deployment unit structure in REPL mode. */ -@Command(name = "structure", description = "Shows the structure of a deployed unit") -public class NodeUnitStructureReplCommand extends BaseCommand implements Runnable { +/** Command to inspect deployment unit in REPL mode. */ +@Command(name = "inspect", description = "Inspects the structure of a deployed unit") +public class NodeUnitInspectReplCommand extends BaseCommand implements Runnable { @Parameters(index = "0", description = "Deployment unit id") private String unitId; @@ -53,7 +53,7 @@ public class NodeUnitStructureReplCommand extends BaseCommand implements Runnabl private boolean plain; @Inject - private NodeUnitStructureCall call; + private NodeUnitInspectCall call; @Inject private ConnectToClusterQuestion question; @@ -61,14 +61,14 @@ public class NodeUnitStructureReplCommand extends BaseCommand implements Runnabl @Override public void run() { runFlow(question.askQuestionIfNotConnected(nodeUrl.getNodeUrl()) - .map(url -> UnitStructureCallInput.builder() + .map(url -> UnitInspectCallInput.builder() .unitId(unitId) .version(version) .url(url) .build()) .then(Flows.fromCall(call)) - .exceptionHandler(ClusterNotInitializedExceptionHandler.createReplHandler("Cannot get unit structure")) - .print(new UnitStructureDecorator(plain)) + .exceptionHandler(ClusterNotInitializedExceptionHandler.createReplHandler("Cannot inspect unit")) + .print(new UnitInspectDecorator(plain)) ); } } diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitReplCommand.java index 3c5616b0ea8..016e44636ce 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitReplCommand.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/node/unit/NodeUnitReplCommand.java @@ -22,7 +22,7 @@ import picocli.CommandLine.Command; /** Manages deployment units on node level in REPL mode. */ @Command(name = "unit", - subcommands = {NodeUnitListReplCommand.class, NodeUnitStructureReplCommand.class}, + subcommands = {NodeUnitListReplCommand.class, NodeUnitInspectReplCommand.class}, description = "Manages deployment units") public class NodeUnitReplCommand extends BaseCommand { } diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecorator.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecorator.java similarity index 96% rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecorator.java rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecorator.java index 868a9cab736..6a5559b3d58 100644 --- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecorator.java +++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecorator.java @@ -26,8 +26,8 @@ import org.apache.ignite.rest.client.model.UnitEntry; import org.apache.ignite.rest.client.model.UnitFile; import org.apache.ignite.rest.client.model.UnitFolder; -/** Decorates unit structure as a tree. */ -public class UnitStructureDecorator implements Decorator<UnitFolder, TerminalOutput> { +/** Decorates unit inspect result as a tree. */ +public class UnitInspectDecorator implements Decorator<UnitFolder, TerminalOutput> { private static final String TREE_BRANCH = "+-- "; private static final String TREE_LAST = "\\-- "; @@ -36,7 +36,7 @@ public class UnitStructureDecorator implements Decorator<UnitFolder, TerminalOut private final boolean plain; - public UnitStructureDecorator(boolean plain) { + public UnitInspectDecorator(boolean plain) { this.plain = plain; } diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCallTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCallTest.java similarity index 93% rename from modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCallTest.java rename to modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCallTest.java index d974d012be9..5d6fab0a2f8 100644 --- a/modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitStructureCallTest.java +++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/call/node/unit/NodeUnitInspectCallTest.java @@ -31,7 +31,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; import com.github.tomakehurst.wiremock.junit5.WireMockTest; import io.micronaut.test.extensions.junit5.annotation.MicronautTest; import jakarta.inject.Inject; -import org.apache.ignite.internal.cli.call.unit.UnitStructureCallInput; +import org.apache.ignite.internal.cli.call.unit.UnitInspectCallInput; import org.apache.ignite.internal.cli.core.call.CallOutput; import org.apache.ignite.rest.client.model.UnitFolder; import org.junit.jupiter.api.BeforeEach; @@ -40,12 +40,12 @@ import org.junit.jupiter.api.Test; @MicronautTest(rebuildContext = true) @WireMockTest -class NodeUnitStructureCallTest { +class NodeUnitInspectCallTest { private String url; @Inject - private NodeUnitStructureCall call; + private NodeUnitInspectCall call; @BeforeEach void setUp(WireMockRuntimeInfo wmRuntimeInfo) { @@ -73,7 +73,7 @@ class NodeUnitStructureCallTest { .willReturn(ok(json))); // When - UnitStructureCallInput input = UnitStructureCallInput.builder() + UnitInspectCallInput input = UnitInspectCallInput.builder() .unitId(unitId) .version(version) .url(url) @@ -100,7 +100,7 @@ class NodeUnitStructureCallTest { .withBody("{\"title\":\"Not Found\",\"status\":404,\"detail\":\"Unit not found\"}"))); // When - UnitStructureCallInput input = UnitStructureCallInput.builder() + UnitInspectCallInput input = UnitInspectCallInput.builder() .unitId(unitId) .version(version) .url(url) @@ -140,7 +140,7 @@ class NodeUnitStructureCallTest { .willReturn(ok(json))); // When - UnitStructureCallInput input = UnitStructureCallInput.builder() + UnitInspectCallInput input = UnitInspectCallInput.builder() .unitId(unitId) .version(version) .url(url) diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecoratorTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecoratorTest.java similarity index 67% rename from modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecoratorTest.java rename to modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecoratorTest.java index 35cb327bdff..f9c302abda8 100644 --- a/modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitStructureDecoratorTest.java +++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/decorators/UnitInspectDecoratorTest.java @@ -19,17 +19,18 @@ package org.apache.ignite.internal.cli.decorators; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.is; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.apache.ignite.rest.client.model.UnitEntry; import org.apache.ignite.rest.client.model.UnitFile; import org.apache.ignite.rest.client.model.UnitFolder; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -class UnitStructureDecoratorTest { +class UnitInspectDecoratorTest { @Test @DisplayName("Tree view should display folder with files") @@ -39,19 +40,16 @@ class UnitStructureDecoratorTest { createFile("file1.txt", 100), createFile("file2.txt", 200)); - UnitStructureDecorator decorator = new UnitStructureDecorator(false); + UnitInspectDecorator decorator = new UnitInspectDecorator(false); // When String output = decorator.decorate(folder).toTerminalString(); // Then - assertThat(output, containsString("test-unit")); - assertThat(output, containsString("file1.txt")); - assertThat(output, containsString("file2.txt")); - assertThat(output, containsString("100 B")); - assertThat(output, containsString("200 B")); - assertThat(output, containsString("+--")); - assertThat(output, containsString("\\--")); + String expected = "test-unit\n" + + "+-- file1.txt (100 B)\n" + + "\\-- file2.txt (200 B)\n"; + assertThat(output, is(expected)); } @Test @@ -69,17 +67,16 @@ class UnitStructureDecoratorTest { .name("root") .children(List.of(subFolderEntry)); - UnitStructureDecorator decorator = new UnitStructureDecorator(false); + UnitInspectDecorator decorator = new UnitInspectDecorator(false); // When String output = decorator.decorate(rootFolder).toTerminalString(); // Then - assertThat(output, containsString("root")); - assertThat(output, containsString("subfolder")); - assertThat(output, containsString("nested.txt")); - assertThat(output, containsString("\\--")); - assertThat(output, containsString(" \\--")); // Nested indent + String expected = "root\n" + + "\\-- subfolder\n" + + " \\-- nested.txt (50 B)\n"; + assertThat(output, is(expected)); } @Test @@ -90,19 +87,15 @@ class UnitStructureDecoratorTest { createFile("file1.txt", 100), createFile("file2.txt", 200)); - UnitStructureDecorator decorator = new UnitStructureDecorator(true); + UnitInspectDecorator decorator = new UnitInspectDecorator(true); // When String output = decorator.decorate(folder).toTerminalString(); // Then - assertThat(output, containsString("file1.txt")); - assertThat(output, containsString("file2.txt")); - assertThat(output, containsString("100")); - assertThat(output, containsString("200")); - // Should not contain tree characters in plain mode - assertThat(output, not(containsString("├──"))); - assertThat(output, not(containsString("└──"))); + String expected = "file1.txt 100\n" + + "file2.txt 200\n"; + assertThat(output, is(expected)); } @Test @@ -120,14 +113,14 @@ class UnitStructureDecoratorTest { .name("root") .children(List.of(subFolderEntry)); - UnitStructureDecorator decorator = new UnitStructureDecorator(true); + UnitInspectDecorator decorator = new UnitInspectDecorator(true); // When String output = decorator.decorate(rootFolder).toTerminalString(); // Then - assertThat(output, containsString("subfolder/nested.txt")); - assertThat(output, containsString("50")); + String expected = "subfolder/nested.txt 50\n"; + assertThat(output, is(expected)); } @Test @@ -139,7 +132,7 @@ class UnitStructureDecoratorTest { createFile("medium.txt", 2048), createFile("large.txt", 1024 * 1024 * 2)); - UnitStructureDecorator decorator = new UnitStructureDecorator(false); + UnitInspectDecorator decorator = new UnitInspectDecorator(false); // When String output = decorator.decorate(folder).toTerminalString(); @@ -159,23 +152,17 @@ class UnitStructureDecoratorTest { .name("empty-folder") .children(List.of()); - UnitStructureDecorator decorator = new UnitStructureDecorator(false); + UnitInspectDecorator decorator = new UnitInspectDecorator(false); // When String output = decorator.decorate(folder).toTerminalString(); // Then - assertThat(output, containsString("empty-folder")); + assertThat(output, is("empty-folder\n")); } - private UnitFolder createFolderWithFiles(String name, UnitFile... files) { - List<UnitEntry> children = new ArrayList<>(); - - for (UnitFile file : files) { - UnitEntry entry = new UnitEntry(); - entry.setActualInstance(file); - children.add(entry); - } + private static UnitFolder createFolderWithFiles(String name, UnitFile... files) { + List<UnitEntry> children = Arrays.stream(files).map(UnitEntry::new).collect(Collectors.toList()); return new UnitFolder() .type(UnitFolder.TypeEnum.FOLDER) @@ -183,7 +170,7 @@ class UnitStructureDecoratorTest { .children(children); } - private UnitFile createFile(String name, long size) { + private static UnitFile createFile(String name, long size) { return new UnitFile() .type(UnitFile.TypeEnum.FILE) .name(name)
