Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ public interface ZeroCodeReportConstants {
String TARGET_REPORT_DIR = "target/zerocode-test-reports/";
String TARGET_FULL_REPORT_CSV_FILE_NAME = "zerocode-junit-granular-report.csv";
String TARGET_FILE_NAME = "target/zerocode-junit-interactive-fuzzy-search.html";
String SUREFIRE_REPORT_DIR = "target/surefire-reports/";
String HIGH_CHART_HTML_FILE_NAME = "zerocode_results_chart";
String REPORT_UPLOAD_DIR = "target/upload-reports/";
String AUTHOR_MARKER_OLD = "@@"; //Deprecated
String AUTHOR_MARKER_NEW = "@";
String CATEGORY_MARKER = "#";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.jsmart.zerocode.core.engine.validators.ZeroCodeValidatorImpl;
import org.jsmart.zerocode.core.report.ZeroCodeReportGenerator;
import org.jsmart.zerocode.core.report.ZeroCodeReportGeneratorImpl;
import org.jsmart.zerocode.core.reportsupload.ReportUploader;
import org.jsmart.zerocode.core.reportsupload.ReportUploaderImpl;
import org.jsmart.zerocode.core.runner.ZeroCodeMultiStepsScenarioRunner;
import org.jsmart.zerocode.core.runner.ZeroCodeMultiStepsScenarioRunnerImpl;

Expand Down Expand Up @@ -68,6 +70,7 @@ public void configure() {
bind(ZeroCodeExternalFileProcessor.class).to(ZeroCodeExternalFileProcessorImpl.class);
bind(ZeroCodeParameterizedProcessor.class).to(ZeroCodeParameterizedProcessorImpl.class);
bind(ZeroCodeSorter.class).to(ZeroCodeSorterImpl.class);
bind(ReportUploader.class).to(ReportUploaderImpl.class);

// ------------------------------------------------
// Bind properties for localhost, CI, DIT, SIT etc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import org.jsmart.zerocode.core.report.ZeroCodeReportGenerator;
import org.jsmart.zerocode.core.reportsupload.ReportUploader;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;
Expand All @@ -16,10 +17,13 @@ public class TestUtilityListener extends RunListener {

private final ZeroCodeReportGenerator reportGenerator;

private final ReportUploader reportUploader;

@Inject
public TestUtilityListener(ObjectMapper mapper, ZeroCodeReportGenerator injectedReportGenerator) {
public TestUtilityListener(ObjectMapper mapper, ZeroCodeReportGenerator injectedReportGenerator, ReportUploader injectedReportUploader) {
this.mapper = mapper;
this.reportGenerator = injectedReportGenerator;
this.reportUploader = injectedReportUploader;
}

@Override
Expand Down Expand Up @@ -50,9 +54,7 @@ private void printTestCompleted() {
* Override this to handle post-finished tasks
*/
public void runPostFinished() {
/*
* Do nothing for now
*/
uploadReports();
}

private void generateChartsAndReports() {
Expand All @@ -71,4 +73,9 @@ private void generateChartsAndReports() {

reportGenerator.generateExtentReport();
}

private void uploadReports(){
reportUploader.uploadReport();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.jsmart.zerocode.core.reportsupload;

public interface ReportUploader {
void uploadReport();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package org.jsmart.zerocode.core.reportsupload;

import com.google.inject.Inject;
import com.google.inject.name.Named;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.jsmart.zerocode.core.constants.ZeroCodeReportConstants;
import org.jsmart.zerocode.core.report.ZeroCodeReportGeneratorImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.*;

public class ReportUploaderImpl implements ReportUploader {

private static final Logger LOGGER = LoggerFactory.getLogger(ZeroCodeReportGeneratorImpl.class);

@Inject(optional = true)
@Named("reports.repo")
private String reportsRepo;

@Inject(optional = true)
@Named("reports.repo.username")
private String reportsRepoUsername;

@Inject(optional = true)
@Named("reports.repo.token")
private String reportsRepoToken;

@Inject(optional = true)
@Named("reports.repo.max.upload.limit.mb")
private Integer reportsRepoMaxUploadLimitMb;


public void uploadReport() {
if (!isAllRequiredVariablesSet()) {
LOGGER.warn("One or more required variables are not set. Skipping report upload.");
return;
}

setDefaultUploadLimit();
createParentDirectoryIfNotExists(new File(ZeroCodeReportConstants.REPORT_UPLOAD_DIR));

try (Git git = initializeOrOpenGitRepository(ZeroCodeReportConstants.REPORT_UPLOAD_DIR)) {
addRemoteRepositoryIfMissing(git);

//Copy files to the repository
copyFile(ZeroCodeReportConstants.TARGET_FILE_NAME, ZeroCodeReportConstants.REPORT_UPLOAD_DIR);
copyFile(
ZeroCodeReportConstants.TARGET_FULL_REPORT_DIR + ZeroCodeReportConstants.TARGET_FULL_REPORT_CSV_FILE_NAME,
ZeroCodeReportConstants.REPORT_UPLOAD_DIR);

copyFirstFileUnder2MBMatchingPattern(
ZeroCodeReportConstants.SUREFIRE_REPORT_DIR,
"*.xml",
ZeroCodeReportConstants.REPORT_UPLOAD_DIR
);
copyFirstFileUnder2MBMatchingPattern(
ZeroCodeReportConstants.TARGET_FULL_REPORT_DIR + "/logs",
"*.log",
ZeroCodeReportConstants.REPORT_UPLOAD_DIR
);
addAndCommitChanges(git);
pushToRemoteRepository(git);
} catch (Exception e) {
LOGGER.warn("Report upload failed: {}", e.getMessage());
}
}

protected void addRemoteRepositoryIfMissing(Git git) throws URISyntaxException, GitAPIException {
if (git.remoteList().call().isEmpty()) {
LOGGER.debug("Adding remote repository: {}", reportsRepo);
git.remoteAdd().setName("origin").setUri(new URIish(reportsRepo)).call();
} else {
LOGGER.debug("Remote repository already exists.");
}
}

protected void addAndCommitChanges(Git git) throws GitAPIException {
git.add().addFilepattern(".").call();
LOGGER.debug("Added all files to the Git index.");

git.commit()
.setMessage("Updated files")
.setAuthor(reportsRepoUsername, reportsRepoUsername)
.call();
LOGGER.debug("Committed changes.");
}

protected void pushToRemoteRepository(Git git) throws GitAPIException {
git.push()
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(reportsRepoUsername, reportsRepoToken))
.call();
LOGGER.debug("Pushed changes to remote repository!");
}

protected boolean isAllRequiredVariablesSet() {
return reportsRepo != null && !reportsRepo.isEmpty() &&
reportsRepoUsername != null && !reportsRepoUsername.isEmpty() &&
reportsRepoToken != null && !reportsRepoToken.isEmpty();
}

protected void setDefaultUploadLimit() {
if (reportsRepoMaxUploadLimitMb == null) {
reportsRepoMaxUploadLimitMb = 2;
LOGGER.debug("reportsRepoMaxUploadLimitMb is not set. Defaulting to 2 MB.");
}
}

protected void createParentDirectoryIfNotExists(File repoDir) {
File parentDir = repoDir.getParentFile();
if (!parentDir.exists() && parentDir.mkdirs()) {
LOGGER.debug("Directory created: {}", parentDir.getAbsolutePath());
} else if (!parentDir.exists()) {
LOGGER.warn("Failed to create directory: {}", parentDir.getAbsolutePath());
}
}

protected Git initializeOrOpenGitRepository(String repoUploadDir) throws IOException, GitAPIException {
if (new File(repoUploadDir, ".git").exists()) {
LOGGER.debug("Existing Git repository found.");
Git git = Git.open(new File(repoUploadDir));
LOGGER.debug("Pulling latest changes from remote repository...");
git.pull()
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(reportsRepoUsername, reportsRepoToken))
.call();
return git;
} else {
LOGGER.debug("Initializing a new Git repository...");
return Git.cloneRepository()
.setURI(reportsRepo)
.setDirectory(new File(repoUploadDir))
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(reportsRepoUsername, reportsRepoToken))
.call();
}
}

protected void copyFile(String sourcePath, String targetDirPath) throws IOException {
File sourceFile = new File(sourcePath);
if (!sourceFile.exists()) {
LOGGER.warn("File not found: {}", sourcePath);
return;
}
if (sourceFile.length() <= reportsRepoMaxUploadLimitMb * 1024 * 1024) {
Files.copy(sourceFile.toPath(), Paths.get(targetDirPath, sourceFile.getName()), StandardCopyOption.REPLACE_EXISTING);
LOGGER.debug("File copied: {}", sourceFile.getName());
} else {
LOGGER.warn("File size exceeds {} MB. Skipping copy: {}", reportsRepoMaxUploadLimitMb, sourceFile.getName());
}
}

protected void copyFirstFileUnder2MBMatchingPattern(String dirPath, String globPattern, String targetDirPath) throws IOException {
Path dir = Paths.get(dirPath);

if (!Files.exists(dir) || !Files.isDirectory(dir)) {
LOGGER.warn("Directory does not exist or is not a valid directory: {}", dirPath);
return;
}
final long maxSizeInBytes = reportsRepoMaxUploadLimitMb * 1024 * 1024;

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, globPattern)) {
for (Path entry : stream) {
if (Files.isRegularFile(entry) && Files.size(entry) <= maxSizeInBytes) {
Path target = Paths.get(targetDirPath, entry.getFileName().toString());
Files.copy(entry, target, StandardCopyOption.REPLACE_EXISTING);
LOGGER.info("Copied first matched file: {}", entry.getFileName());
return;
}
}
LOGGER.warn("No file under 2MB found matching pattern: {}", globPattern);
}
}


public void setReportsRepo(String reportsRepo) {
this.reportsRepo = reportsRepo;
}

public void setReportsRepoUsername(String reportsRepoUsername) {
this.reportsRepoUsername = reportsRepoUsername;
}

public void setReportsRepoToken(String reportsRepoToken) {
this.reportsRepoToken = reportsRepoToken;
}

public void setReportsRepoMaxUploadLimitMb(Integer reportsRepoMaxUploadLimitMb) {
if (reportsRepoMaxUploadLimitMb == null) {
this.reportsRepoMaxUploadLimitMb = 2;
}else {
this.reportsRepoMaxUploadLimitMb = reportsRepoMaxUploadLimitMb;
}

}
}
Loading