Skip to content

Commit

Permalink
test: mock maven interaction in Integration test
Browse files Browse the repository at this point in the history
To overcome bug of running dependency tree maven plugin in a github action workflow runner, with any combination of java + maven

Signed-off-by: Zvi Grinberg <zgrinber@redhat.com>
  • Loading branch information
zvigrinberg committed Mar 5, 2024
1 parent f346768 commit c6d2d17
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
43 changes: 40 additions & 3 deletions src/test/java/com/redhat/exhort/impl/ExhortApiIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,36 @@
import com.redhat.exhort.api.ProviderReport;
import com.redhat.exhort.providers.HelperExtension;
import com.redhat.exhort.tools.Ecosystem;
import com.redhat.exhort.tools.Operations;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static com.redhat.exhort.providers.Java_Maven_Provider_Test.getOutputFileAndOverwriteItWithMock;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;

@Tag("IntegrationTest")
@ExtendWith(HelperExtension.class)
@ExtendWith(MockitoExtension.class)
class ExhortApiIT extends ExhortTest {

private static Api api;
private static Map<String,String> ecoSystemsManifestNames;

private MockedStatic<Operations> mockedOperations;
@BeforeAll
static void beforeAll() {
api = new ExhortApi();
Expand All @@ -67,16 +75,32 @@ void Integration_Test_End_To_End_Stack_Analysis(Ecosystem.Type packageManager) t
String manifestFileName = ecoSystemsManifestNames.get(packageManager.getType());
String pathToManifest = getFileFromResource(manifestFileName, "tst_manifests", "it", packageManager.getType(), manifestFileName);
preparePythonEnvironment(packageManager);
// Github action runner with all maven and java versions seems to enter infinite loop in integration tests of MAVEN when runnig dependency maven plugin to produce verbose text dependenct tree format.
// locally it's not recreated with same versions
mockMavenDependencyTree(packageManager);
releaseStaticMock(packageManager);
AnalysisReport analysisReportResult = api.stackAnalysis(pathToManifest).get();
handleJsonResponse(analysisReportResult,true);
}

private void releaseStaticMock(Ecosystem.Type packageManager) {
if(packageManager.equals(Ecosystem.Type.MAVEN)) {
this.mockedOperations.close();
}
}


@Tag("IntegrationTest")
@ParameterizedTest
@EnumSource(value = Ecosystem.Type.class, names = { "GOLANG", "MAVEN", "NPM", "PYTHON" })
void Integration_Test_End_To_End_Stack_Analysis_Mixed(Ecosystem.Type packageManager) throws IOException, ExecutionException, InterruptedException {
String manifestFileName = ecoSystemsManifestNames.get(packageManager.getType());
String pathToManifest = getFileFromResource(manifestFileName, "tst_manifests", "it", packageManager.getType(), manifestFileName);
preparePythonEnvironment(packageManager);
// Github action runner with all maven and java versions seems to enter infinite loop in integration tests of MAVEN when runnig dependency maven plugin to produce verbose text dependenct tree format.
// locally it's not recreated with same versions
mockMavenDependencyTree(packageManager);
releaseStaticMock(packageManager);
AnalysisReport analysisReportJson = api.stackAnalysisMixed(pathToManifest).get().json;
String analysisReportHtml = new String(api.stackAnalysisMixed(pathToManifest).get().html);
handleJsonResponse(analysisReportJson,true);
Expand All @@ -90,6 +114,10 @@ void Integration_Test_End_To_End_Stack_Analysis_Html(Ecosystem.Type packageManag
String manifestFileName = ecoSystemsManifestNames.get(packageManager.getType());
String pathToManifest = getFileFromResource(manifestFileName, "tst_manifests", "it", packageManager.getType(), manifestFileName);
preparePythonEnvironment(packageManager);
// Github action runner with all maven and java versions seems to enter infinite loop in integration tests of MAVEN when runnig dependency maven plugin to produce verbose text dependenct tree format.
// locally it's not recreated with same versions
mockMavenDependencyTree(packageManager);
releaseStaticMock(packageManager);
String analysisReportHtml = new String(api.stackAnalysisHtml(pathToManifest).get());
handleHtmlResponse(analysisReportHtml);
}
Expand All @@ -101,7 +129,7 @@ void Integration_Test_End_To_End_Stack_Analysis_Html(Ecosystem.Type packageManag
void Integration_Test_End_To_End_Component_Analysis(Ecosystem.Type packageManager) throws IOException, ExecutionException, InterruptedException {
String manifestFileName = ecoSystemsManifestNames.get(packageManager.getType());
byte[] manifestContent = getStringFromFile("tst_manifests", "it", packageManager.getType(), manifestFileName).getBytes();
preparePythonEnvironment(packageManager);
preparePythonEnvironment(packageManager);
AnalysisReport analysisReportResult = api.componentAnalysis(manifestFileName,manifestContent).get();
handleJsonResponse(analysisReportResult,false);
}
Expand Down Expand Up @@ -155,7 +183,16 @@ private void handleHtmlResponse(String analysisReportHtml) throws JsonProcessing
assertTrue(status.get("ok").asBoolean(false));

}

private void mockMavenDependencyTree(Ecosystem.Type packageManager) throws IOException {
if(packageManager.equals(Ecosystem.Type.MAVEN)) {
mockedOperations = mockStatic(Operations.class);
String depTree;
try (var is = getResourceAsStreamDecision(getClass(), new String [] { "tst_manifests", "it","maven", "depTree.txt"})) {
depTree = new String(is.readAllBytes());
}
mockedOperations.when(() -> Operations.runProcess(any(),any())).thenAnswer(invocationOnMock -> getOutputFileAndOverwriteItWithMock(depTree, invocationOnMock, "-DoutputFile"));
}
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@

@ExtendWith(HelperExtension.class)
@ExtendWith(MockitoExtension.class)
class Java_Maven_Provider_Test extends ExhortTest {
public class Java_Maven_Provider_Test extends ExhortTest {


// private static System.Logger log = System.getLogger("Java_Maven_Provider_Test");
// test folder are located at src/test/resources/tst_manifests
// each folder should contain:
Expand Down Expand Up @@ -100,7 +102,7 @@ void test_the_provideStack(String testFolder) throws IOException, InterruptedExc

}

private static String getOutputFileAndOverwriteItWithMock(String outputFileContent, InvocationOnMock invocationOnMock,String parameterPrefix) throws IOException {
public static String getOutputFileAndOverwriteItWithMock(String outputFileContent, InvocationOnMock invocationOnMock,String parameterPrefix) throws IOException {
String[] rawArguments = (String[]) invocationOnMock.getRawArguments()[0];
Optional<String> outputFileArg = Arrays.stream(rawArguments).filter(arg -> arg!= null && arg.startsWith(parameterPrefix)).findFirst();
String outputFilePath=null;
Expand Down
6 changes: 6 additions & 0 deletions src/test/resources/tst_manifests/it/maven/depTree.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pom-with-deps-no-ignore:pom-with-dependency-not-ignored-for-tests:jar:0.0.1
+- log4j:log4j:jar:1.2.17:compile
+- org.projectlombok:lombok:jar:1.16.6:compile
\- com.fasterxml.jackson.core:jackson-databind:jar:2.14.0:compile
+- com.fasterxml.jackson.core:jackson-annotations:jar:2.14.0:compile
\- com.fasterxml.jackson.core:jackson-core:jar:2.14.0:compile

0 comments on commit c6d2d17

Please sign in to comment.