All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.siwenyan.superglue.team.TeamBase Maven / Gradle / Ivy

There is a newer version: 1.25.a
Show newest version
package com.github.siwenyan.superglue.team;

import com.github.siwenyan.common.ImmediateAbortException;
import com.github.siwenyan.common.Retry;
import com.github.siwenyan.common.StringTools;
import com.github.siwenyan.common.Sys;
import com.github.siwenyan.superglue.AbstractStepSet;
import com.github.siwenyan.superglue.Login;
import com.github.siwenyan.web.LostBrowserException;
import com.github.siwenyan.web.WebUtils;
import cucumber.api.Scenario;
import org.apache.log4j.Logger;
import org.junit.Assert;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Queue;

public abstract class TeamBase extends AbstractStepSet {
    private static final Logger log = Logger.getLogger(TeamBase.class.getName());

    protected final Map pf;
    private final String objectNameKey;

    protected Map> outcome = new LinkedHashMap<>();

    private long teamworkTimeoutInMillis = Integer.parseInt(Sys.conf.getProperty("teamworkTimeoutInMinutes")) * 60 * 1000;

    public TeamBase(Scenario scenario, Map pf, String objectNameKey) throws LostBrowserException {
        super(scenario, Login.login(scenario, pf));
        this.pf = pf;
        this.objectNameKey = objectNameKey;
    }

    protected abstract Queue buildTeam(Map pf);

    protected abstract void kickOff();

    protected abstract void immediateRecover();

    public Map> getOutcome() {
        return this.outcome;
    }

    public final boolean teamwork() {
        return teamwork(teamworkTimeoutInMillis);
    }

    public final boolean teamwork(long teamworkTimeoutInMillis) {

        boolean success = new Retry("teamwork>" + StringTools.shortName(this.getClass()), teamworkTimeoutInMillis, 0, 0) {

            @Override
            protected void tryOnce() throws Exception {
                try {
                    if ("true".equalsIgnoreCase(Sys.conf.getProperty("team.retryWithNewBrowser"))) {
                        Login.quitScenarioLogins(scenario());
                    }

                    LinkedHashMap pfWorking = new LinkedHashMap<>(pf);
                    setDriver(Login.login(scenario(), pfWorking));

                    Queue team = buildTeam(pfWorking);
                    stopAtNextPageBegin(pfWorking, team);

                    String continueFromPage = pfWorking.get(PageWorkerBase.CONTINUE_FROM_PAGE);
                    if (!StringTools.isEmpty(continueFromPage)) {
                        while (null != team.peek() && !team.peek().getPageName().contains(continueFromPage)) {
                            team.poll();
                        }
                    }

                    Assert.assertTrue("No workers.", !team.isEmpty());

                    outcome.clear();
                    teamworkInQueue(team);
                } catch (StopAtPageBeginException e) {
                    scenarioLogger.warn("Stop at page begin: " + e.getMessage());
                } catch (StopAtPageException e) {
                    scenarioLogger.warn("Stop at page: " + e.getMessage());
                }
            }

            @Override
            protected void weakRecover(Exception e) throws Exception {
                String continueFromPage = pf.get(PageWorkerBase.CONTINUE_FROM_PAGE);
                if (!StringTools.isEmpty(continueFromPage)) {
                    throw new ImmediateAbortException("Unable to retry with " + PageWorkerBase.CONTINUE_FROM_PAGE + "=" + continueFromPage);
                }
            }

        }.execute();

        String note = (success ? "Success: " : "Timeout: ") + pf.get(objectNameKey);
        WebUtils.demoBreakPoint(scenario(), null, note);

        return success;

    }

    private static void stopAtNextPageBegin(LinkedHashMap pf, Queue team) {
        String stopAtNextPageBegin = pf.get(PageWorkerBase.STOP_AT_NEXT_PAGE_BEGIN);
        if (!StringTools.isEmpty(stopAtNextPageBegin)) {
            String nextPage = null;
            for (PageWorkerBase worker : team) {
                if (null != nextPage) {
                    nextPage = worker.getPageName();
                    break;
                }
                if (stopAtNextPageBegin.equals(worker.getPageName()) || stopAtNextPageBegin.equals(worker.getShortPageName())) {
                    nextPage = "";
                }
            }
            if (!StringTools.isEmpty(nextPage)) {
                pf.put(PageWorkerBase.STOP_AT_PAGE_BEGIN, nextPage);
            }
        }
    }

    private void teamworkInQueue(Queue workersInQueue)
            throws StopAtPageBeginException, StopAtPageException {

        PageWorkerBase firstWorker = workersInQueue.peek();
        boolean kickoffSuccess = new Retry("teamworkInQueue.kickoff>" + StringTools.shortName(this.getClass())) {
            @Override
            protected void tryOnce() throws Exception {
                kickOff();
            }

            @Override
            protected void weakRecover(Exception e) throws Exception {
                immediateRecover();
            }

            @Override
            protected boolean until() throws Exception {
                return firstWorker.accept();
            }

            @Override
            protected boolean untilRecover(Exception e) throws Exception {
                return firstWorker.acceptRecover(e);
            }
        }.execute();

        if (kickoffSuccess) {
            scenarioLogger.highlight("Kickoff success.");
        } else {
            scenarioLogger.error("Kickoff fail.");
            throw new RuntimeException("Unable to kickOff");
        }

        while (null != workersInQueue.peek()) {
            PageWorkerBase worker = workersInQueue.poll();

            worker.tryStopAtPageBegin();

            boolean workSuccess = new Retry("teamworkInQueue.work>" + StringTools.shortName(this.getClass()) + ">" + worker.getShortPageName()) {
                @Override
                protected void tryOnce() throws Exception {
                    worker.work();
                }

                @Override
                protected void weakRecover(Exception e) throws Exception {
                    immediateRecover();
                }
            }.execute();

            if (workSuccess) {
                scenarioLogger.highlight("Work success: " + worker.toString());
            } else {
                scenarioLogger.error("Work fail:" + worker.toString());
                throw new RuntimeException("Unable to work: " + worker.toString());
            }

            Map> workerOutCome = worker.getOutcome();
            if (null != workerOutCome) {
                outcome.putAll(workerOutCome);
            }

            worker.tryStopAtPage();

            boolean handOffSuccess = true;
            PageWorkerBase nextWorker = workersInQueue.peek();
            String phrase = " [" + worker.getShortPageName() + "] ==> [" + (null == nextWorker ? "" : nextWorker.getShortPageName()) + "]";
            if (null != nextWorker) {
                handOffSuccess = new Retry("Retry hand off and accept " + phrase, 2 * 60 * 1000, 1000, 1000) {

                    @Override
                    protected void tryOnce() throws Exception {
                        worker.handOff();
                    }

                    @Override
                    protected void weakRecover(Exception e) throws Exception {
                        immediateRecover();
                        worker.handOffRecover(e);
                    }

                    @Override
                    protected boolean until() throws Exception {
                        return nextWorker.accept();
                    }

                    @Override
                    protected boolean untilRecover(Exception e) throws Exception {
                        //immediateRecover();
                        return nextWorker.acceptRecover(e);
                    }
                }.execute();
            }
            if (handOffSuccess) {
                scenarioLogger.highlight("Hand off and accept success:" + phrase);
            } else {
                scenarioLogger.error("Hand off or accept fail:" + phrase);
                throw new RuntimeException("Unable to hand off or accept:" + phrase);
            }
        }

        boolean endSuccess = new Retry("teamworkInQueue.end>" + StringTools.shortName(this.getClass())) {
            @Override
            protected void tryOnce() throws Exception {
                end();
            }

            @Override
            protected void weakRecover(Exception e) throws Exception {
                immediateRecover();
            }
        }.execute();

        if (endSuccess) {
            scenarioLogger.highlight("End success.");
        } else {
            scenarioLogger.error("End fail.");
            throw new RuntimeException("Unable to end");
        }

    }

    protected void end() {
        // do nothing by default
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy