Skip to content

Commit

Permalink
some report updates, fix for #24 ExecutionResultsCollector working in…
Browse files Browse the repository at this point in the history
… forked mode
  • Loading branch information
iantmoore committed Sep 28, 2016
1 parent 7524f94 commit b660123
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 50 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Requirements
* 3 progress bars rather than one, toggle to show data in original tabular form
* Step implementation method usage report (Beta)
* Replaced hand rolled recursive File listing with commons.io implementation
* Fixed Issue #24 - ExecutionResultsCollector didn't work with forked mode

1.0.3
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,25 @@ public SubstepExecutionFailure getFailure() {
return substepExecutionFailure;
}

public Long getStartedAt() {
return startedAt;
}

public Long getCompletedAt() {
return completedAt;
}

public void setStartedAt(Long startedAt) {
this.startedAt = startedAt;
}

public void setCompletedAt(Long completedAt) {
this.completedAt = completedAt;
}

public void setSubstepExecutionFailure(SubstepExecutionFailure substepExecutionFailure) {
this.substepExecutionFailure = substepExecutionFailure;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public class StepImplementationNode extends ExecutionNode implements StepNode {
private final transient Class<?> targetClass;
private final transient Method targetMethod;

private final String targetClassName;
private final String methodName;

private final Set<String> tags;

// FIXME: RB I'd prefer this to be final, it's like this because of the builder.
Expand All @@ -46,6 +49,19 @@ public StepImplementationNode(final Class<?> targetClass, final Method targetMet
this.targetMethod = targetMethod;
this.setDepth(depth);
this.tags = tags;

if (targetClass.getDeclaringClass() != null) {
this.targetClassName = targetClass.getDeclaringClass().getName();
}
else {
this.targetClassName = targetClass.getName();
}
if (targetMethod != null){
this.methodName = targetMethod.getName();
}
else {
this.methodName = null;
}
}


Expand Down Expand Up @@ -138,8 +154,7 @@ public Set<String> getTags() {

@Override
public String toDebugString() {
return super.toDebugString() + " impl: "
+ this.targetMethod.getDeclaringClass().getSimpleName() + "." + this.targetMethod.getName();
return super.toDebugString() + " impl: " + targetClassName + "." + methodName;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,9 @@ private void doNotification(final IExecutionNode node) {

this.notificationSequenceNumber++;


n.setUserData(getBytes(node.getResult()));

this.log.trace("sending notification for node id: " + node.getId() + " sequence: "
log.trace("sending notification for node id: " + node.getId() + " sequence: "
+ this.notificationSequenceNumber);

sendNotification(n);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ object ExecutionResultsCollector{

class ExecutionResultsCollector extends IExecutionResultsCollector {

private val log: Logger = LoggerFactory.getLogger(classOf[ExecutionResultsCollector])
@transient
private lazy val log: Logger = LoggerFactory.getLogger(classOf[ExecutionResultsCollector])

var dataDir: File = new File(".")
var pretty : Boolean = false
Expand All @@ -49,20 +50,26 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
@transient
lazy val UTF8 = Charset.forName("UTF-8")

var featureToResultsDirMap: Map[FeatureNode, File] = Map()
var featureToResultsDirMap: Map[Long, File] = Map()

val scenarioSummaryMap = new mutable.HashMap[Long, (BasicScenarioNode, File)]

def onNodeFailed(node: IExecutionNode, cause: Throwable): Unit = {

log.debug("ExecutionResultsCollector nodeFailed: " + node.getId)


node match {
case scenarioNode : BasicScenarioNode => {
log.debug("basic scenario failed")

val feature = getFeatureFromNode(scenarioNode)

featureToResultsDirMap.get(feature) match {
case None => log.error("no report dir for feature: " + feature.getFilename)
featureToResultsDirMap.get(feature.getId) match {
case None => {
log.error("scenario node failed - no report dir for feature: " + feature.getFilename + " id: " + feature.getId)

}
case Some(dir) => {

// write out a results file for this scenario
Expand All @@ -81,26 +88,22 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
log.debug("feature node failed")

// write a summary file for the feature
featureToResultsDirMap.get(featureNode) match {
case None => log.error("no report dir for feature: " + featureNode.getFilename)
featureToResultsDirMap.get(featureNode.getId) match {
case None => {
log.error("feature node failed - no report dir for feature: " + featureNode.getFilename+ " id: " + featureNode.getId)
}
case Some(dir) => {
val summaryFile = new File(dir, dir.getName + ".json")

Files.write(generateJson(featureNode), summaryFile, UTF8)

}
}

}
case rootNode : RootNode => {
log.debug("root node failed")
val summaryFile = new File(dataDir, "results.json")

Files.write(generateJson(rootNode), summaryFile, UTF8)




}

case _ => log.debug("other node failed")
Expand All @@ -111,7 +114,7 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
def onNodeStarted(node: IExecutionNode): Unit = {

// do we care about nodes starting ?

log.debug("ExecutionResultsCollector nodeStarted: " + node.getId)
}

def getFeatureFromNode(node: IExecutionNode) : FeatureNode = {
Expand All @@ -127,13 +130,18 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {

def onNodeFinished(node: IExecutionNode): Unit = {

log.debug("ExecutionResultsCollector nodeFinished: " + node.getId)


node match {
case scenarioNode : BasicScenarioNode => {
log.debug("basic scenario finished")
val feature = getFeatureFromNode(scenarioNode)

featureToResultsDirMap.get(feature) match {
case None => log.error("no report dir for feature: " + feature.getFilename)
featureToResultsDirMap.get(feature.getId) match {
case None => {
log.error("basic scenario node finished - no report dir for feature: " + feature.getFilename + " id: " + feature.getId)
}
case Some(dir) => {

// write out a results file for this scenario
Expand All @@ -152,8 +160,10 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
log.debug("feature node finished")

// write a summary file for the feature
featureToResultsDirMap.get(featureNode) match {
case None => log.error("no report dir for feature: " + featureNode.getFilename)
featureToResultsDirMap.get(featureNode.getId) match {
case None => {
log.error("feature node finished - no report dir for feature: " + featureNode.getFilename + " id: " + featureNode.getId)
}
case Some(dir) => {
val summaryFile = new File(dir, dir.getName + ".json")

Expand All @@ -172,9 +182,6 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
case stepImplNode : StepImplementationNode => {
log.debug("stepImpl Node finished")



stepImplNode.getParent
}
case _ => log.debug("other node finished")
}
Expand All @@ -183,6 +190,8 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {

def onNodeIgnored(node: IExecutionNode): Unit = {

log.debug("ExecutionResultsCollector nodeIgnored: " + node.getId)

node match {
case scenarioNode : BasicScenarioNode => {

Expand All @@ -199,9 +208,9 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
rootNode.getChildren.asScala.map(f => {

val featureResultsDir =
featureToResultsDirMap.get(f) match {
featureToResultsDirMap.get(f.getId) match {
case None => {
log.error("no report dir for feature: " + f.getFilename)
log.error("generateJson for RootNode - no report dir for feature: " + f.getFilename)
""
}
case Some(dir) => dir.getName
Expand Down Expand Up @@ -330,18 +339,19 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {
}
}

log.debug("collecting data into " + dataDir.getAbsolutePath)

log.info("collecting data into " + dataDir.getAbsolutePath)

// create subdirs for each feature

val featureNodes = rootNode.getChildren.asScala

log.debug("init dirs for " + featureNodes.size + " features")

val featureNames =
featureNodes.map(featureNode => featureNode.getFilename)
featureNodes.map(featureNode => featureNode.getFilename)

val dupes =
if (featureNames.distinct.size < featureNames.size){
if (featureNames.distinct.size <= featureNames.size){
// take into account the same feature files in different dirs - featureNode.getFileUri

val uniqueFeatureNamesMap: Map[String, mutable.Buffer[String]] = featureNames.groupBy(identity)
Expand Down Expand Up @@ -372,7 +382,9 @@ class ExecutionResultsCollector extends IExecutionResultsCollector {

featureResultsDir.mkdir()

featureNode -> featureResultsDir
log.debug("mapping feature node id " + featureNode.getId + " to dir: " + featureResultsDir.getAbsolutePath)

featureNode.getId -> featureResultsDir
}).toMap
}
}
Expand Down
17 changes: 12 additions & 5 deletions core/src/main/scala/org/substeps/report/Model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ case object Counters {

// println(s"$total : Int, $run: Int, $passed: Int, $failed: Int, $skipped: Int")

val passedPC = pc(passed, total)
val failedPC = pc(failed, total)
val skippedPC = pc(skipped, total)

new Counters(total, run, passed, failed, skipped,
pc(passed, total),
pc(skipped, total),
pc(failed, total))
passedPC,
skippedPC,
failedPC)
}

def pc (num : Int, total : Int) = {
Expand All @@ -29,14 +33,17 @@ case object Counters {
case _ => {
val numerator = BigDecimal.valueOf(num.toLong)
val denominator = BigDecimal(total.toDouble)
((numerator / denominator) * 100).setScale(2, BigDecimal.RoundingMode.HALF_DOWN).doubleValue()
((numerator / denominator) * 100).setScale(2, BigDecimal.RoundingMode.DOWN).doubleValue()
}
}

}
}

case class Counters(total : Int, run: Int, passed: Int, failed: Int, skipped: Int, successPC : Double, skippedPC : Double, failedPC : Double, tag: Option[String] = None ) {
case class Counters(total : Int, run: Int, passed: Int, failed: Int, skipped: Int,
successPC : Double,
skippedPC : Double,
failedPC : Double, tag: Option[String] = None ) {

def + (that: Counters) : Counters = {
Counters.build(this.total + that.total,
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/substeps/report/ReportFrame.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ trait ReportFrameTemplate {
| <div class="progress">
| <div class="progress-bar progress-bar-success" style="width: ${counters.successPC}%;">${counters.successPC} Success (${counters.passed})</div>
| <div class="progress-bar progress-bar-danger" style="width: ${counters.failedPC}%">${counters.failedPC}% Failure (${counters.failed})</div>
| <div class="progress-bar progress-bar-warning progress-bar-striped" style="width: ${counters.skippedPC}%">${counters.skipped}%</div>
| <div class="progress-bar progress-bar-warning" style="width: ${counters.skippedPC}%">${counters.skippedPC}% Not run (${counters.skipped})</div>
| </div>
|
| </div>
Expand Down
Loading

0 comments on commit b660123

Please sign in to comment.