ru.yandex.qatools.allure.storages.StepStorage Maven / Gradle / Ivy
The newest version!
package ru.yandex.qatools.allure.storages;
import ru.yandex.qatools.allure.model.Status;
import ru.yandex.qatools.allure.model.Step;
import java.util.Deque;
import java.util.LinkedList;
/**
* Using to storage information about current step context. How it works:
*
* create new step storage | root() -> null
* start step1 | step1() -> root() -> null
* finish step1 | root(step1()) -> null
* start step2 | step2() -> root(step1()) -> null
* finish step2 | root(step1() -> step2()) -> null
* ...
*
* In the end just get all children of root step. It's step three which you can see in report
*
* @author Dmitry Baev [email protected]
* Date: 13.12.13
*
* @see ru.yandex.qatools.allure.Allure
*/
public class StepStorage extends InheritableThreadLocal> {
public static final Object LOCK = new Object();
/**
* Returns the current thread's "initial value". Construct an new
* {@link java.util.Deque} with root step {@link #createRootStep()}
*
* @return the initial value for this thread-local
*/
@Override
protected Deque initialValue() {
Deque queue = new LinkedList<>();
queue.add(createRootStep());
return queue;
}
/**
* In case parent thread spawn thread we need create a new queue
* for child thread but use the only one root step. In the end all steps will be
* children of root step, all we need is sync adding steps
* @param parentValue value from parent thread
* @return local copy of queue in this thread with parent root as first element
*/
@Override
protected Deque childValue(Deque parentValue) {
Deque queue = new LinkedList<>();
queue.add(parentValue.getFirst());
return queue;
}
/**
* Retrieves, but does not remove, the last element of this deque.
*
* @return the tail of this deque
*/
public Step getLast() {
return get().getLast();
}
/**
* Inserts the specified element into the queue represented by this deque
*
* @param step the element to add
*/
public void put(Step step) {
synchronized (LOCK) {
get().add(step);
}
}
/**
* Removes the last element of deque in the current thread's copy of this
* thread-local variable. If after this deque is empty add new root step
* {@link #createRootStep()}
*
* @return the element removed from deque
*/
public Step pollLast() {
Deque queue = get();
Step last = queue.pollLast();
if (queue.isEmpty()) {
queue.add(createRootStep());
}
return last;
}
/**
* Move last step to children of previous step. How it works:
*
* before: step1(...) -> step2(child1 -> ... -> childN) -> step3(...) -> ... -> null
* after: step2(child1 -> ... -> childN -> step1(...)) -> step3(...) -> ... -> null
*
* @return ex-last step
*/
public Step adopt() {
Step step = pollLast();
synchronized (LOCK) {
getLast().getSteps().add(step);
}
return step;
}
/**
* Construct new root step. Used for inspect problems with Allure lifecycle
*
* @return new root step marked as broken
*/
public Step createRootStep() {
return new Step()
.withName("Root step")
.withTitle("Allure step processing error: if you see this step something went wrong.")
.withStart(System.currentTimeMillis())
.withStatus(Status.BROKEN);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy