Skip to content
Closed
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
* Allow parameter-types in escaped optional groups ([#cucumber/572](https://github.com/cucumber/cucumber/pull/572), [#cucumber/561](https://github.com/cucumber/cucumber/pull/561) Luke Hill, Jayson Smith, M.P. Korstanje)
* Prefer expression with the longest non-empty match ([#cucumber/580](https://github.com/cucumber/cucumber/pull/580) M.P. Korstanje)
* Improve heuristics for creating Cucumber/Regular Expressions from strings ([#cucumber/518](https://github.com/cucumber/cucumber/pull/518) Aslak Hellesøy)
* [Kotlin-Java8] Upgrade Kotlin to v1.3.0 and more idiomatic Kotlin ([#1590](https://github.com/cucumber/cucumber-jvm/pull/1590) Marit van Dijk)

### Deprecated

Expand Down Expand Up @@ -42,7 +43,7 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
### Fixed
* [Core] Disambiguate between Windows drive letter and uri scheme ([#1568](https://github.com/cucumber/cucumber-jvm/issues/1568), [#1564](https://github.com/cucumber/cucumber-jvm/issues/1564) jsa34)

## [4.2.3-SNAPSHOT](https://github.com/cucumber/cucumber-jvm/compare/v4.2.2...v4.2.3) (2019-02-08)
## [4.2.3](https://github.com/cucumber/cucumber-jvm/compare/v4.2.2...v4.2.3) (2019-02-08)

### Fixed
* [Build] Fix windows build ([#1552](https://github.com/cucumber/cucumber-jvm/pull/1552), [#1551](https://github.com/cucumber/cucumber-jvm/issues/1551) Alexey Mozhenin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

public final class TestCaseStarted extends TestCaseEvent {
public final TestCase testCase;
private final long elapsedTimiMillis;

public TestCaseStarted(Long timeStamp, TestCase testCase) {
public TestCaseStarted(Long timeStamp, Long elapsedTimiMillis, TestCase testCase) {
super(timeStamp, testCase);
this.testCase = testCase;
this.elapsedTimiMillis = elapsedTimiMillis;
}

public long getElapsedTimiMillis() {
return elapsedTimiMillis;
}

}
2 changes: 2 additions & 0 deletions core/src/main/java/io/cucumber/core/event/EventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public interface EventBus extends EventPublisher {

Long getTime();

Long getElapsedTimeMillis();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, but getTimeStampMillis.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its the elapsed time since epoch in millis so i named it that way. But i ll update the name no problem.


void send(Event event);

void sendAll(Iterable<Event> queue);
Expand Down
66 changes: 43 additions & 23 deletions core/src/main/java/io/cucumber/core/plugin/JSONFormatter.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
package io.cucumber.core.plugin;

import io.cucumber.core.api.event.HookTestStep;
import io.cucumber.core.api.event.HookType;
import io.cucumber.core.api.event.PickleStepTestStep;
import io.cucumber.core.api.event.Result;
import io.cucumber.core.api.event.TestCase;
import io.cucumber.core.api.event.TestStep;
import io.cucumber.core.api.event.EmbedEvent;
import io.cucumber.core.api.event.EventHandler;
import io.cucumber.core.api.event.EventListener;
import io.cucumber.core.api.event.EventPublisher;
import io.cucumber.core.api.event.TestCaseStarted;
import io.cucumber.core.api.event.TestRunFinished;
import io.cucumber.core.api.event.TestSourceRead;
import io.cucumber.core.api.event.TestStepFinished;
import io.cucumber.core.api.event.TestStepStarted;
import io.cucumber.core.api.event.WriteEvent;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import gherkin.ast.Background;
import gherkin.ast.Feature;
import gherkin.ast.ScenarioDefinition;
Expand All @@ -29,11 +22,22 @@
import gherkin.pickles.PickleString;
import gherkin.pickles.PickleTable;
import gherkin.pickles.PickleTag;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.cucumber.core.api.event.EmbedEvent;
import io.cucumber.core.api.event.EventHandler;
import io.cucumber.core.api.event.EventListener;
import io.cucumber.core.api.event.EventPublisher;
import io.cucumber.core.api.event.HookTestStep;
import io.cucumber.core.api.event.HookType;
import io.cucumber.core.api.event.PickleStepTestStep;
import io.cucumber.core.api.event.Result;
import io.cucumber.core.api.event.TestCase;
import io.cucumber.core.api.event.TestCaseStarted;
import io.cucumber.core.api.event.TestRunFinished;
import io.cucumber.core.api.event.TestSourceRead;
import io.cucumber.core.api.event.TestStep;
import io.cucumber.core.api.event.TestStepFinished;
import io.cucumber.core.api.event.TestStepStarted;
import io.cucumber.core.api.event.WriteEvent;

public final class JSONFormatter implements EventListener {
private String currentFeatureFile;
Expand All @@ -47,6 +51,7 @@ public final class JSONFormatter implements EventListener {
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private final NiceAppendable out;
private final TestSourcesModel testSources = new TestSourcesModel();
private DateTimeFormatter dateTimeFormatter;

private EventHandler<TestSourceRead> testSourceReadHandler = new EventHandler<TestSourceRead>() {
@Override
Expand Down Expand Up @@ -118,7 +123,7 @@ private void handleTestCaseStarted(TestCaseStarted event) {
featureMaps.add(currentFeatureMap);
currentElementsList = (List<Map<String, Object>>) currentFeatureMap.get("elements");
}
currentTestCaseMap = createTestCase(event.testCase);
currentTestCaseMap = createTestCase(event);
if (testSources.hasBackground(currentFeatureFile, event.testCase.getLine())) {
currentElementMap = createBackground(event.testCase);
currentElementsList.add(currentElementMap);
Expand Down Expand Up @@ -187,8 +192,13 @@ private Map<String, Object> createFeatureMap(TestCase testCase) {
return featureMap;
}

private Map<String, Object> createTestCase(TestCase testCase) {
private Map<String, Object> createTestCase(TestCaseStarted event) {
Map<String, Object> testCaseMap = new HashMap<String, Object>();

testCaseMap.put("start_timestamp", getDateTimeFromTimeStamp(event));

TestCase testCase = event.getTestCase();

testCaseMap.put("name", testCase.getName());
testCaseMap.put("line", testCase.getLine());
testCaseMap.put("type", "scenario");
Expand All @@ -212,6 +222,11 @@ private Map<String, Object> createTestCase(TestCase testCase) {
return testCaseMap;
}

private String getDateTimeFromTimeStamp(TestCaseStarted event) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(event.getElapsedTimiMillis()), ZoneId.systemDefault());
return localDateTime.format(dateTimeFormatter == null ? DateTimeFormatter.ISO_DATE_TIME : dateTimeFormatter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason the dateTimeFormatter is optional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the JSON output the format should be fixed predictable. So I would think the zone should always be UTC. Using a ZonedDateTime may be more appropriate but I'm not sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And probably good to bear in mind that v4 is still using Java 7. So you can't use the fancy Date stuff yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And well Java 7 puts away both the localdatetime and zonedatetime options away.
I ll change it to the usual Date.

And shouldn't it just be the default zone of the PC running the TCs? In case they use it to see the timestamp of the TC run in the report.

Copy link
Contributor Author

@zutshiy zutshiy Mar 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the dateTimeFormatter optional for the sake of flexibility in case we don't want the full time in some cases (we just want the date, etc).

Its actually also being used in the JUnits to bypass the 'dynamic generation' issue, for eg in RuntimeTest, JsonParallelRuntimeTest. I can make it constant but I ll need some suggestion on how to update the JUnits then. Do u have an idea?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to depend on the default timezone of the machine running the tests, as this might be either a local machine with locally running application, or a CI server (i.e. Jenkins) running tests against an actual environment; where the CI server and the test environment might not have the same system datetime / timezone. Being able to specify it is preferable inho

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that makes sense. I can change it to always be UTC in that case.

But do u mean allow the user to specify what timezone to use before running the tests? From cucumber options or the like?

}

private Map<String, Object> createBackground(TestCase testCase) {
TestSourcesModel.AstNode astNode = testSources.getAstNode(currentFeatureFile, testCase.getLine());
if (astNode != null) {
Expand Down Expand Up @@ -378,4 +393,9 @@ private Map<String, Object> createResultMap(Result result) {
}
return resultMap;
}

public void setDateTimeFormatter(DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}

}
20 changes: 11 additions & 9 deletions core/src/main/java/io/cucumber/core/runner/TestCase.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package io.cucumber.core.runner;

import io.cucumber.core.api.event.Result;
import io.cucumber.core.api.event.TestStep;
import io.cucumber.core.api.event.TestCaseFinished;
import io.cucumber.core.api.event.TestCaseStarted;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import gherkin.events.PickleEvent;
import gherkin.pickles.PickleLocation;
import gherkin.pickles.PickleTag;
import io.cucumber.core.api.event.Result;
import io.cucumber.core.api.event.TestCaseFinished;
import io.cucumber.core.api.event.TestCaseStarted;
import io.cucumber.core.api.event.TestStep;
import io.cucumber.core.event.EventBus;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

final class TestCase implements io.cucumber.core.api.event.TestCase {
private final PickleEvent pickleEvent;
private final List<PickleStepTestStep> testSteps;
Expand All @@ -35,7 +35,9 @@ public TestCase(List<PickleStepTestStep> testSteps,
void run(EventBus bus) {
boolean skipNextStep = this.dryRun;
Long startTime = bus.getTime();
bus.send(new TestCaseStarted(startTime, this));
Long startTimeMillis = bus.getElapsedTimeMillis();

bus.send(new TestCaseStarted(startTime, startTimeMillis, this));
Scenario scenario = new Scenario(bus, this);

for (HookTestStep before : beforeHooks) {
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/io/cucumber/core/runner/TimeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

public interface TimeService {
long time();
long elapsedTimeMillis();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here timeMillis.


TimeService SYSTEM = new TimeService() {
@Override
public long time() {
return System.nanoTime();
}

@Override
public long elapsedTimeMillis() {
return System.currentTimeMillis();
}
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ public final class TimeServiceEventBus extends AbstractEventBus {
public TimeServiceEventBus(TimeService stopWatch) {
this.stopWatch = stopWatch;
}

@Override
public Long getTime() {
return stopWatch.time();
}

public Long getElapsedTimeMillis() {
return stopWatch.elapsedTimeMillis();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import io.cucumber.core.api.event.Event;
import io.cucumber.core.api.event.EventHandler;
import io.cucumber.core.backend.BackendSupplier;
import io.cucumber.core.backend.ObjectFactory;
import io.cucumber.core.backend.ObjectFactorySupplier;
import io.cucumber.core.event.AbstractEventBus;
import io.cucumber.core.event.EventBus;
Expand Down Expand Up @@ -62,6 +61,12 @@ public void send(final Event event) {
super.send(event);
parent.send(event);
}

@Override
public Long getElapsedTimeMillis()
{
return parent.getElapsedTimeMillis();
}
}

private static final class SynchronizedEventBus implements EventBus {
Expand Down Expand Up @@ -104,5 +109,10 @@ public synchronized <T extends Event> void registerHandlerFor(Class<T> eventType
public synchronized <T extends Event> void removeHandlerFor(Class<T> eventType, EventHandler<T> handler) {
delegate.removeHandlerFor(eventType, handler);
}

@Override
public Long getElapsedTimeMillis() {
return delegate.getElapsedTimeMillis();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@ static long getTime() {
return new Date().getTime();
}

private static long getTimeInMillis() {
return System.currentTimeMillis();
}

static Event createTestCaseEvent(final String uri, final int line) {
final TestCase testCase = mock(TestCase.class);
given(testCase.getUri()).willReturn(uri);
given(testCase.getLine()).willReturn(line);
return new TestCaseStarted(getTime(), testCase);
return new TestCaseStarted(getTime(), getTimeInMillis(), testCase);
}


private Event runStarted = new TestRunStarted(getTime());
private Event testRead = new TestSourceRead(getTime(), "uri", "source");
private Event suggested = new SnippetsSuggestedEvent(getTime(), "uri", Collections.<PickleLocation>emptyList(), Collections.<String>emptyList());
Expand Down
Loading