Skip to content

Commit

Permalink
move model to separate project (#5)
Browse files Browse the repository at this point in the history
* log

* refactor: move model to separate project so can use in other projects to parse test xml

* refactor: move model to separate project so can use in other projects to parse test xml

* add test

* refactor

* tests passing after refactor

* add utils for parsing result from surefire xml dir

* add result test

* support absolute paths

* refactor

Co-authored-by: eric.r.driggs <[email protected]>
  • Loading branch information
ericdriggs and eric.r.driggs authored May 4, 2022
1 parent ed12a3c commit c8eb358
Show file tree
Hide file tree
Showing 111 changed files with 2,209 additions and 222 deletions.
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,34 @@ TODO PROTOTYPE:

* enum status

TODO MVP:
* secure secrets (env vars ok, expiring tokens better)
* db migration tool (flyway)
* tests for uniqueness constraints all tables
Roadmaps
V0.0 (MVP)
GOAL: publish data for jive api test, report as json
* [3] e2e manual test working locally
* [2] provision nonprod db with access to credentials
* [2] use to publish data for jive api test
* [1] use hard-coded key (committed) to encode secrets so not plain text
* [2] publish docker image for server
* [1] publish java client as jar using github package https://blog.dipien.
* [3] misc testing / cleanupcom/how-to-publish-your-internal-artifacts-to-github-packages-5447e7e82e80

Est total: for mvp 14 points

V0.1 (Phase 1 rollout)
GOAL: html report, documentation explaining value proposition and usage
* Documentation explaining value proposition and usage
* render html report from json (manual strings or rocker templating engine)
* secure db credentials using vault or aws

v0.2 (Phase 2 maintenance)
* retention cleanup (default 90 days for main/master/develop branch, 30 days for feature branch)
* admin user

v0.3 (Configuration)
* retention configuration (specify global default retention duration and allow override duration for branches)
* api for roles and permissions
* tokens?

Nice to have for later versions
* see if we can distinguish between different failure reasons for the same test to assign a similarity score to failures so we can see if failing for multiple reasons.
** test reports run over a fixed time period. Failures can be partioned by percent with same similarity (e.g. 90% for text A, 10% for text B)
4 changes: 3 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
springBootVersion = 2.4.5
springDependencyVersion = 1.0.10.RELEASE
springDependencyVersion = 1.0.10.RELEASE
lombokVersion = 1.18.20
jakartaVersion = '2.3.3'
7 changes: 0 additions & 7 deletions reportcard-client/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ dependencies {
implementation group: 'commons-io', name: 'commons-io', version: '2.8.0'

implementation 'org.springframework.boot:spring-boot-starter-webflux'
// implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
// implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion"
// runtime 'org.slf4j:jul-to-slf4j:1.7.30'
}

tasks.withType(Test) {
useJUnitPlatform()
}

sourceSets {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package com.ericdriggs.reportcard.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import reactor.core.publisher.Mono;

import java.util.List;

@SpringBootApplication
public class ClientApplication implements ApplicationRunner {
private static Logger log = LoggerFactory.getLogger(ClientApplication.class);

public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
Expand All @@ -15,20 +21,21 @@ public static void main(String[] args) {

@Override
public void run(ApplicationArguments args) {
//FIXME: either don't log args or mask password
System.out.println("# NonOptionArgs: " + args.getNonOptionArgs().size());
//TODO: either don't log args or mask password(s)
log.info("# NonOptionArgs: " + args.getNonOptionArgs().size());

System.out.println("NonOptionArgs:");
log.info("NonOptionArgs:");
args.getNonOptionArgs().forEach(System.out::println);

System.out.println("# OptionArgs: " + args.getOptionNames().size());
System.out.println("OptionArgs:");
log.info("# OptionArgs: " + args.getOptionNames().size());
log.info("OptionArgs:");

args.getOptionNames().forEach(optionName -> System.out.println(optionName + "=" + args.getOptionValues(optionName)));

PostRequest scannerPostRequest = ClientProperties.getReportPostPayload(args);



PostRequest postRequest = ClientProperties.getReportPostPayload(args);
Mono<String> postResultMono = PostWebClient.INSTANCE.postTestReport(postRequest);
String postResult = postResultMono.block();
log.info("postResult:\n " + postResult);
}

}
46 changes: 46 additions & 0 deletions reportcard-model/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
buildscript {
ext {
jakartaVersion = '2.3.3'
lombokVersion = '1.18.20'
jacksonVersion = '2.13.2'
junitVersion = '5.7.1'
}
}

plugins {
id 'java'
id 'groovy'
id 'idea'
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenLocal()
mavenCentral()
jcenter()
}

dependencies {
//Lombok
implementation "org.projectlombok:lombok:${lombokVersion}"
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"

//JSON
implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"

//XML
compile "jakarta.xml.bind:jakarta.xml.bind-api:${jakartaVersion}"
runtime "com.sun.xml.bind:jaxb-impl:${jakartaVersion}"

//Mapping
implementation 'org.modelmapper:modelmapper:2.3.0'

//Test
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
}
5 changes: 5 additions & 0 deletions reportcard-model/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is generated by the 'io.freefair.lombok' Gradle plugin
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
lombok.accessors.chain = true
lombok.equalsAndHashCode.callSuper = call
64 changes: 64 additions & 0 deletions reportcard-model/src/main/java/com/ericdriggs/file/FileUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.ericdriggs.file;

import lombok.SneakyThrows;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileUtils {

public static String absolutePathFromRelativePath (String relativePath) {
return Path.of(Path.of("").toString(), relativePath).toAbsolutePath().toString();
}

public static String regexForExtension (String fileNameExtension) {
return ".*[.]" + fileNameExtension;
}

public static List<String> fileContentsFromPathAndRegex(String absolutePath, String fileNameRegex) {
List<String> absolutePaths = filePathsForPathAndRegex(absolutePath, fileNameRegex);
return fileContentsFromPaths(absolutePaths);
}


public static List<String> fileContentsFromPaths(List<String> absolutePaths) {
List<String> fileContents = new ArrayList<>();
for ( String absolutePath : absolutePaths) {
fileContents.add(stringFromPath(absolutePath));
}
return fileContents;
}


@SneakyThrows(IOException.class)
public static List<String> filePathsForPathAndRegex(String absolutePath, String fileNameRegex) {
Path dirPath = Path.of(absolutePath);

//not recursive
final int maxDepth = 1;

try (Stream<Path> walk = Files.find(
dirPath,
maxDepth,
(path, basicFileAttributes) -> path.toFile().getName().matches(fileNameRegex))) {

List<String> result = walk.filter(Files::isRegularFile)
.map(x -> x.toAbsolutePath().toString())
.collect(Collectors.toList());
return result;
}
}

@SneakyThrows(IOException.class)
public static String stringFromPath(String absolutePath) {
return Files.readString(Path.of(absolutePath));
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ericdriggs.reportcard.model;

import com.ericdriggs.reportcard.model.converter.surefire.SurefireConvertersUtil;
import com.ericdriggs.reportcard.xml.surefire.SurefireParserUtil;
import com.ericdriggs.reportcard.xml.surefire.Testsuite;

import java.util.List;

public enum ResultParserUtil {

;//static methods only
private static final String XML_EXTENSION_REGEX = ".*[.]xml";

public static TestResult fromSurefirePath(String absolutePath) {
return fromSurefirePathAndRegex(absolutePath, XML_EXTENSION_REGEX);
}


public static TestResult fromSurefirePathAndRegex(String absolutePath, String fileNameRegex) {
List<Testsuite> testsuites = SurefireParserUtil.parseTestSuitesFromPathAndRegex(absolutePath, fileNameRegex);
return SurefireConvertersUtil.doFromSurefireToModelTestResult(testsuites);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.ericdriggs.reportcard.model;

public class TestCase extends com.ericdriggs.reportcard.gen.db.tables.pojos.TestCase {
import com.ericdriggs.reportcard.xml.ResultCount;

public class TestCase extends com.ericdriggs.reportcard.pojos.TestCase {
private TestStatus testStatus;

public TestCase setTestStatus(TestStatus testStatus) {
Expand All @@ -22,4 +23,8 @@ public TestStatus getTestStatus() {
}
return testStatus;
}

public ResultCount getResultCount() {
return testStatus.getResultCount();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ericdriggs.reportcard.model;

import com.ericdriggs.reportcard.xml.ResultCount;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

Expand All @@ -8,8 +9,8 @@
import java.util.Map;
import java.util.Objects;

public class TestResult extends com.ericdriggs.reportcard.gen.db.tables.pojos.TestResult {
private List<TestSuite> testSuites = new ArrayList<>();
public class TestResult extends com.ericdriggs.reportcard.pojos.TestResult {
private List<TestSuite> testSuites = new ArrayList<>();

public List<TestSuite> getTestSuites() {
return testSuites;
Expand Down Expand Up @@ -71,4 +72,12 @@ protected String getExternalLinksJson(Map<String,String> externalLinksMap) {
}
}

public ResultCount getResultCount() {
ResultCount resultCount = new ResultCount();
for (TestSuite testSuite : testSuites) {
ResultCount testSuiteResultCount = testSuite.getResultCount();
resultCount.add(resultCount);
}
return resultCount;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ericdriggs.reportcard.model;

import com.ericdriggs.reportcard.xml.ResultCount;

import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -51,4 +53,7 @@ public static TestStatus fromStatusId(int statusId) {
return testStatus;
}

public ResultCount getResultCount() {
return this.getTestStatusType().getResultCount();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.ericdriggs.reportcard.model;

import com.ericdriggs.reportcard.xml.ResultCount;

public enum TestStatusType {
SUCCESS(new ResultCount().setTests(1).setSuccesses(1)),
SKIPPED(new ResultCount().setTests(1).setSkipped(1)),
FAILURE(new ResultCount().setTests(1).setFailures(1)),
ERROR(new ResultCount().setTests(1).setErrors(1));

private ResultCount resultCount;

TestStatusType(ResultCount resultCount) {
this.resultCount = resultCount;
}

public ResultCount getResultCount() {
return resultCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.ericdriggs.reportcard.model;

import com.ericdriggs.reportcard.xml.ResultCount;
import java.util.ArrayList;
import java.util.List;

public class TestSuite extends com.ericdriggs.reportcard.pojos.TestSuite {
private List<TestCase> testCases = new ArrayList<>();

public List<TestCase> getTestCases() {
return testCases;
}

public TestSuite setTestCases( List<TestCase> testCases) {
this.testCases = testCases;
return this;
}


public ResultCount getResultCount() {
ResultCount resultCount = new ResultCount();
for(TestCase testCase : testCases) {
resultCount.add(testCase.getResultCount());
}
return resultCount;
}

public static ResultCount getResultCount(List<TestSuite> testSuites) {
ResultCount resultCount = new ResultCount();
for (TestSuite testSuite : testSuites) {
resultCount.add(testSuite.getResultCount());
}
return resultCount;
}
}
Loading

0 comments on commit c8eb358

Please sign in to comment.