text:
package org.apache.storm.daemon.worker;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import org.apache.storm.Config;
import org.apache.storm.Constants;
import org.apache.storm.StormTimer;
import org.apache.storm.cluster.IStateStorage;
import org.apache.storm.cluster.IStormClusterState;
import org.apache.storm.cluster.VersionedData;
import org.apache.storm.daemon.StormCommon;
import org.apache.storm.daemon.supervisor.AdvancedFSOps;
import org.apache.storm.executor.IRunningExecutor;
import org.apache.storm.generated.Assignment;
import org.apache.storm.generated.DebugOptions;
import org.apache.storm.generated.Grouping;
import org.apache.storm.generated.InvalidTopologyException;
import org.apache.storm.generated.NodeInfo;
import org.apache.storm.generated.StormBase;
import org.apache.storm.generated.StormTopology;
import org.apache.storm.generated.StreamInfo;
import org.apache.storm.generated.TopologyStatus;
import org.apache.storm.grouping.Load;
import org.apache.storm.grouping.LoadMapping;
import org.apache.storm.hooks.BaseWorkerHook;
import org.apache.storm.messaging.ConnectionWithStatus;
import org.apache.storm.messaging.DeserializingConnectionCallback;
import org.apache.storm.messaging.IConnection;
import org.apache.storm.messaging.IContext;
import org.apache.storm.messaging.TaskMessage;
import org.apache.storm.messaging.TransportFactory;
import org.apache.storm.serialization.KryoTupleSerializer;
import org.apache.storm.task.WorkerTopologyContext;
import org.apache.storm.tuple.AddressedTuple;
import org.apache.storm.tuple.Fields;
import org.apache.storm.utils.ConfigUtils;
import org.apache.storm.utils.Utils;
import org.apache.storm.utils.DisruptorQueue;
import org.apache.storm.utils.ObjectReader;
import org.apache.storm.utils.ThriftTopologyUtils;
import org.apache.storm.utils.TransferDrainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;

public class WorkerState {

    private static final Logger LOG = LoggerFactory.getLogger(WorkerState.class);

    final Map<String, Object> conf;
    final IContext mqContext;

    public Map getConf() {
        return conf;
    }

    public IConnection getReceiver() {
        return receiver;
    }

    public String getTopologyId() {
        return topologyId;
    }

    public int getPort() {
        return port;
    }

    public String getWorkerId() {
        return workerId;
    }

    public IStateStorage getStateStorage() {
        return stateStorage;
    }

    public AtomicBoolean getIsTopologyActive() {
        return isTopologyActive;
    }

    public AtomicReference<Map<String, DebugOptions>> getStormComponentToDebug() {
        return stormComponentToDebug;
    }

    public Set<List<Long>> getExecutors() {
        return executors;
    }

    public List<Integer> getTaskIds() {
        return taskIds;
    }

    public Map getTopologyConf() {
        return topologyConf;
    }

    public StormTopology getTopology() {
        return topology;
    }

    public StormTopology getSystemTopology() {
        return systemTopology;
    }

    public Map<Integer, String> getTaskToComponent() {
        return taskToComponent;
    }

    public Map<String, Map<String, Fields>> getComponentToStreamToFields() {
        return componentToStreamToFields;
    }

    public Map<String, List<Integer>> getComponentToSortedTasks() {
        return componentToSortedTasks;
    }

    public Map<String, Long> getBlobToLastKnownVersion() {return blobToLastKnownVersion;}

    public AtomicReference<Map<NodeInfo, IConnection>> getCachedNodeToPortSocket() {
        return cachedNodeToPortSocket;
    }

    public Map<List<Long>, DisruptorQueue> getExecutorReceiveQueueMap() {
        return executorReceiveQueueMap;
    }

    public Runnable getSuicideCallback() {
        return suicideCallback;
    }

    public Utils.UptimeComputer getUptime() {
        return uptime;
    }

    public Map<String, Object> getDefaultSharedResources() {
        return defaultSharedResources;
    }

    public Map<String, Object> getUserSharedResources() {
        return userSharedResources;
    }

    final IConnection receiver;
    final String topologyId;
    final String assignmentId;
    final int port;
    final String workerId;
    final IStateStorage stateStorage;
    final IStormClusterState stormClusterState;

    // when worker bootup, worker will start to setup initial connections to
    // other workers. When all connection is ready, we will enable this flag
    // and spout and bolt will be activated.
    // used in worker only, keep it as atomic
    final AtomicBoolean isWorkerActive;
    final AtomicBoolean isTopologyActive;
    final AtomicReference<Map<String, DebugOptions>> stormComponentToDebug;

    // executors and taskIds running in this worker
    final Set<List<Long>> executors;
    final List<Integer> taskIds;
    final Map<String, Object> topologyConf;
    final StormTopology topology;
    final StormTopology systemTopology;
    final Map<Integer, String> taskToComponent;
    final Map<String, Map<String, Fields>> componentToStreamToFields;
    final Map<String, List<Integer>> componentToSortedTasks;
    final ConcurrentMap<String, Long> blobToLastKnownVersion;
    final ReentrantReadWriteLock endpointSocketLock;
    final AtomicReference<Map<Integer, NodeInfo>> cachedTaskToNodePort;
    final AtomicReference<Map<NodeInfo, IConnection>> cachedNodeToPortSocket;
    final Map<List<Long>, DisruptorQueue> executorReceiveQueueMap;
    // executor id is in form [start_task_id end_task_id]
    // short executor id is start_task_id
    final Map<Integer, DisruptorQueue> shortExecutorReceiveQueueMap;
    final Map<Integer, Integer> taskToShortExecutor;
    final Runnable suicideCallback;
    final Utils.UptimeComputer uptime;
    final Map<String, Object> defaultSharedResources;
    final Map<String, Object> userSharedResources;
    final LoadMapping loadMapping;
    final AtomicReference<Map<String, VersionedData<Assignment>>> assignmentVersions;
    // Whether this worker is going slow. 0 indicates the backpressure is off
    final AtomicLong backpressure = new AtomicLong(0);
    // How long until the backpressure znode is invalid.
    final long backpressureZnodeTimeoutMs;
    // If the transfer queue is backed-up
    final AtomicBoolean transferBackpressure = new AtomicBoolean(false);
    // a trigger for synchronization with executors
    final AtomicBoolean backpressureTrigger = new AtomicBoolean(false);
    // whether the throttle is activated for spouts
    final AtomicBoolean throttleOn = new AtomicBoolean(false);

    public LoadMapping getLoadMapping() {
        return loadMapping;
    }

    public AtomicReference<Map<String, VersionedData<Assignment>>> getAssignmentVersions() {
        return assignmentVersions;
    }

    public AtomicBoolean getBackpressureTrigger() {
        return backpressureTrigger;
    }

    public AtomicBoolean getThrottleOn() {
        return throttleOn;
    }

    public DisruptorQueue getTransferQueue() {
        return transferQueue;
    }

    public StormTimer getUserTimer() {
        return userTimer;
    }

    final DisruptorQueue transferQueue;

    // Timers
    final StormTimer heartbeatTimer = mkHaltingTimer("heartbeat-timer");
    final StormTimer refreshLoadTimer = mkHaltingTimer("refresh-load-timer");
    final StormTimer refreshConnectionsTimer = mkHaltingTimer("refresh-connections-timer");
    final StormTimer refreshCredentialsTimer = mkHaltingTimer("refresh-credentials-timer");
    final StormTimer checkForUpdatedBlobsTimer = mkHaltingTimer("check-for-updated-blobs-timer");
    final StormTimer resetLogLevelsTimer = mkHaltingTimer("reset-log-levels-timer");
    final StormTimer refreshActiveTimer = mkHaltingTimer("refresh-active-timer");
    final StormTimer executorHeartbeatTimer = mkHaltingTimer("executor-heartbeat-timer");
    final StormTimer refreshBackpressureTimer = mkHaltingTimer("refresh-backpressure-timer");
    final StormTimer userTimer = mkHaltingTimer("user-timer");

    // global variables only used internally in class
    private final Set<Integer> outboundTasks;
    private final AtomicLong nextUpdate = new AtomicLong(0);
    private final boolean trySerializeLocal;
    private final TransferDrainer drainer;

    private static final long LOAD_REFRESH_INTERVAL_MS = 5000L;

    public WorkerState(Map<String, Object> conf, IContext mqContext, String topologyId, String assignmentId, int port, String workerId,
        Map<String, Object> topologyConf, IStateStorage stateStorage, IStormClusterState stormClusterState)
        throws IOException, InvalidTopologyException {
        this.executors = new HashSet<>(readWorkerExecutors(stormClusterState, topologyId, assignmentId, port));
        this.transferQueue = new DisruptorQueue("worker-transfer-queue",
            ObjectReader.getInt(topologyConf.get(Config.TOPOLOGY_TRANSFER_BUFFER_SIZE)),
            (long) topologyConf.get(Config.TOPOLOGY_DISRUPTOR_WAIT_TIMEOUT_MILLIS),
            ObjectReader.getInt(topologyConf.get(Config.TOPOLOGY_DISRUPTOR_BATCH_SIZE)),
            (long) topologyConf.get(Config.TOPOLOGY_DISRUPTOR_BATCH_TIMEOUT_MILLIS));

        this.conf = conf;
        this.mqContext = (null != mqContext) ? mqContext : TransportFactory.makeContext(topologyConf);
        this.receiver = this.mqContext.bind(topologyId, port);
        this.topologyId = topologyId;
        this.assignmentId = assignmentId;
        this.port = port;
        this.workerId = workerId;
        this.stateStorage = stateStorage;
        this.stormClusterState = stormClusterState;
        this.isWorkerActive = new AtomicBoolean(false);
        this.isTopologyActive = new AtomicBoolean(false);
        this.stormComponentToDebug = new AtomicReference<>();
        this.executorReceiveQueueMap = mkReceiveQueueMap(topologyConf, executors);
        this.shortExecutorReceiveQueueMap = new HashMap<>();
        this.taskIds = new ArrayList<>();
        this.blobToLastKnownVersion = new ConcurrentHashMap<>();
        for (Map.Entry<List<Long>, DisruptorQueue> entry : executorReceiveQueueMap.entrySet()) {
            this.shortExecutorReceiveQueueMap.put(entry.getKey().get(0).intValue(), entry.getValue());
            this.taskIds.addAll(StormCommon.executorIdToTasks(entry.getKey()));
        }
        Collections.sort(taskIds);
        this.topologyConf = topologyConf;
        this.backpressureZnodeTimeoutMs = ObjectReader.getInt(topologyConf.get(Config.BACKPRESSURE_ZNODE_TIMEOUT_SECS)) * 1000;
        this.topology = ConfigUtils.readSupervisorTopology(conf, topologyId, AdvancedFSOps.make(conf));
        this.systemTopology = StormCommon.systemTopology(topologyConf, topology);
        this.taskToComponent = StormCommon.stormTaskInfo(topology, topologyConf);
        this.componentToStreamToFields = new HashMap<>();
        for (String c : ThriftTopologyUtils.getComponentIds(systemTopology)) {
            Map<String, Fields> streamToFields = new HashMap<>();
            for (Map.Entry<String, StreamInfo> stream : ThriftTopologyUtils.getComponentCommon(systemTopology, c).get_streams().entrySet()) {
                streamToFields.put(stream.getKey(), new Fields(stream.getValue().get_output_fields()));
            }
            componentToStreamToFields.put(c, streamToFields);
        }
        this.componentToSortedTasks = Utils.reverseMap(taskToComponent);
        this.componentToSortedTasks.values().forEach(Collections::sort);
        this.endpointSocketLock = new ReentrantReadWriteLock();
        this.cachedNodeToPortSocket = new AtomicReference<>(new HashMap<>());
        this.cachedTaskToNodePort = new AtomicReference<>(new HashMap<>());
        this.taskToShortExecutor = new HashMap<>();
        for (List<Long> executor : this.executors) {
            for (Integer task : StormCommon.executorIdToTasks(executor)) {
                taskToShortExecutor.put(task, executor.get(0).intValue());
            }
        }
        this.suicideCallback = Utils.mkSuicideFn();
        this.uptime = Utils.makeUptimeComputer();
        this.defaultSharedResources = makeDefaultResources();
        this.userSharedResources = makeUserResources();
        this.loadMapping = new LoadMapping();
        this.assignmentVersions = new AtomicReference<>(new HashMap<>());
        this.outboundTasks = workerOutboundTasks();
        this.trySerializeLocal = topologyConf.containsKey(Config.TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZE)
            && (Boolean) topologyConf.get(Config.TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZE);
        if (trySerializeLocal) {
            LOG.warn("WILL TRY TO SERIALIZE ALL TUPLES (Turn off {} for production", Config.TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZE);
        }
        this.drainer = new TransferDrainer();

    }

    public void refreshConnections() {
        try {
            refreshConnections(() -> refreshConnectionsTimer.schedule(0, this::refreshConnections));
        } catch (Exception e) {
            throw Utils.wrapInRuntime(e);
        }
    }

    public void refreshConnections(Runnable callback) throws Exception {
        Integer version = stormClusterState.assignmentVersion(topologyId, callback);
        version = (null == version) ? 0 : version;
        VersionedData<Assignment> assignmentVersion = assignmentVersions.get().get(topologyId);
        Assignment assignment;
        if (null != assignmentVersion && (assignmentVersion.getVersion() == version)) {
            assignment = assignmentVersion.getData();
        } else {
            VersionedData<Assignment>
                newAssignmentVersion = new VersionedData<>(version,
                stormClusterState.assignmentInfoWithVersion(topologyId, callback).getData());
            assignmentVersions.getAndUpdate(prev -> {
                Map<String, VersionedData<Assignment>> next = new HashMap<>(prev);
                next.put(topologyId, newAssignmentVersion);
                return next;
            });
            assignment = newAssignmentVersion.getData();
        }

        Set<NodeInfo> neededConnections = new HashSet<>();
        Map<Integer, NodeInfo> newTaskToNodePort = new HashMap<>();
        if (null != assignment) {
            Map<Integer, NodeInfo> taskToNodePort = StormCommon.taskToNodeport(assignment.get_executor_node_port());
            for (Map.Entry<Integer, NodeInfo> taskToNodePortEntry : taskToNodePort.entrySet()) {
                Integer task = taskToNodePortEntry.getKey();
                if (outboundTasks.contains(task)) {
                    newTaskToNodePort.put(task, taskToNodePortEntry.getValue());
                    if (!taskIds.contains(task)) {
                        neededConnections.add(taskToNodePortEntry.getValue());
                    }
                }
            }
        }

        Set<NodeInfo> currentConnections = cachedNodeToPortSocket.get().keySet();
        Set<NodeInfo> newConnections = Sets.difference(neededConnections, currentConnections);
        Set<NodeInfo> removeConnections = Sets.difference(currentConnections, neededConnections);

        // Add new connections atomically
        cachedNodeToPortSocket.getAndUpdate(prev -> {
            Map<NodeInfo, IConnection> next = new HashMap<>(prev);
            for (NodeInfo nodeInfo : newConnections) {
                next.put(nodeInfo,
                    mqContext.connect(
                        topologyId,
                        assignment.get_node_host().get(nodeInfo.get_node()),    // Host
                        nodeInfo.get_port().iterator().next().intValue()));     // Port
            }
            return next;
        });

        try {
            endpointSocketLock.writeLock().lock();
            cachedTaskToNodePort.set(newTaskToNodePort);
        } finally {
            endpointSocketLock.writeLock().unlock();
        }

        for (NodeInfo nodeInfo : removeConnections) {
            cachedNodeToPortSocket.get().get(nodeInfo).close();
        }

        // Remove old connections atomically
        cachedNodeToPortSocket.getAndUpdate(prev -> {
            Map<NodeInfo, IConnection> next = new HashMap<>(prev);
            removeConnections.forEach(next::remove);
            return next;
        });

    }

    public void refreshStormActive() {
        refreshStormActive(() -> refreshActiveTimer.schedule(0, this::refreshStormActive));
    }

    public void refreshStormActive(Runnable callback) {
        StormBase base = stormClusterState.stormBase(topologyId, callback);
        isTopologyActive.set(
            (null != base) &&
            (base.get_status() == TopologyStatus.ACTIVE) &&
            (isWorkerActive.get()));
        if (null != base) {
            Map<String, DebugOptions> debugOptionsMap = new HashMap<>(base.get_component_debug());
            for (DebugOptions debugOptions : debugOptionsMap.values()) {
                if (!debugOptions.is_set_samplingpct()) {
                    debugOptions.set_samplingpct(10);
                }
                if (!debugOptions.is_set_enable()) {
                    debugOptions.set_enable(false);
                }
            }
            stormComponentToDebug.set(debugOptionsMap);
            LOG.debug("Events debug options {}", stormComponentToDebug.get());
        }
    }

    public void refreshThrottle() {
        boolean backpressure = stormClusterState.topologyBackpressure(topologyId, backpressureZnodeTimeoutMs, this::refreshThrottle);
        this.throttleOn.set(backpressure);
    }

    private static double getQueueLoad(DisruptorQueue q) {
        DisruptorQueue.QueueMetrics qMetrics = q.getMetrics();
        return ((double) qMetrics.population()) / qMetrics.capacity();
    }

    public void refreshLoad(List<IRunningExecutor> execs) {
        Set<Integer> remoteTasks = Sets.difference(new HashSet<>(outboundTasks), new HashSet<>(taskIds));
        Long now = System.currentTimeMillis();
        Map<Integer, Double> localLoad = new HashMap<>();
        for (IRunningExecutor exec: execs) {
            double receiveLoad = getQueueLoad(exec.getReceiveQueue());
            double sendLoad = getQueueLoad(exec.getSendQueue());
            localLoad.put(exec.getExecutorId().get(0).intValue(), Math.max(receiveLoad, sendLoad));
        }

        Map<Integer, Load> remoteLoad = new HashMap<>();
        cachedNodeToPortSocket.get().values().stream().forEach(conn -> remoteLoad.putAll(conn.getLoad(remoteTasks)));
        loadMapping.setLocal(localLoad);
        loadMapping.setRemote(remoteLoad);

        if (now > nextUpdate.get()) {
            receiver.sendLoadMetrics(localLoad);
            nextUpdate.set(now + LOAD_REFRESH_INTERVAL_MS);
        }
    }

    /**
     * we will wait all connections to be ready and then activate the spout/bolt
     * when the worker bootup
     */
    public void activateWorkerWhenAllConnectionsReady() {
        int delaySecs = 0;
        int recurSecs = 1;
        refreshActiveTimer.schedule(delaySecs, new Runnable() {
            @Override public void run() {
                if (areAllConnectionsReady()) {
                    LOG.info("All connections are ready for worker {}:{} with id {}", assignmentId, port, workerId);
                    isWorkerActive.set(Boolean.TRUE);
                } else {
                    refreshActiveTimer.schedule(recurSecs, () -> activateWorkerWhenAllConnectionsReady(), false, 0);
                }
            }
        });
    }

    public void registerCallbacks() {
        LOG.info("Registering IConnectionCallbacks for {}:{}", assignmentId, port);
        receiver.registerRecv(new DeserializingConnectionCallback(topologyConf,
            getWorkerTopologyContext(),
            this::transferLocal));
    }

    public void transferLocal(List<AddressedTuple> tupleBatch) {
        Map<Integer, List<AddressedTuple>> grouped = new HashMap<>();
        for (AddressedTuple tuple : tupleBatch) {
            Integer executor = taskToShortExecutor.get(tuple.dest);
            if (null == executor) {
                LOG.warn("Received invalid messages for unknown tasks. Dropping... ");
                continue;
            }
            List<AddressedTuple> current = grouped.get(executor);
            if (null == current) {
                current = new ArrayList<>();
                grouped.put(executor, current);
            }
            current.add(tuple);
        }

        for (Map.Entry<Integer, List<AddressedTuple>> entry : grouped.entrySet()) {
            DisruptorQueue queue = shortExecutorReceiveQueueMap.get(entry.getKey());
            if (null != queue) {
                queue.publish(entry.getValue());
            } else {
                LOG.warn("Received invalid messages for unknown tasks. Dropping... ");
            }
        }
    }

    public void transfer(KryoTupleSerializer serializer, List<AddressedTuple> tupleBatch) {
        if (trySerializeLocal) {
            assertCanSerialize(serializer, tupleBatch);
        }
        List<AddressedTuple> local = new ArrayList<>();
        Map<Integer, List<TaskMessage>> remoteMap = new HashMap<>();
        for (AddressedTuple addressedTuple : tupleBatch) {
            int destTask = addressedTuple.getDest();
            if (taskIds.contains(destTask)) {
                // Local task
                local.add(addressedTuple);
            } else {
                // Using java objects directly to avoid performance issues in java code
                if (! remoteMap.containsKey(destTask)) {
                    remoteMap.put(destTask, new ArrayList<>());
                }
                remoteMap.get(destTask).add(new TaskMessage(destTask, serializer.serialize(addressedTuple.getTuple())));
            }
        }

        if (!local.isEmpty()) {
            transferLocal(local);
        }
        if (!remoteMap.isEmpty()) {
            transferQueue.publish(remoteMap);
        }
    }

    // TODO: consider having a max batch size besides what disruptor does automagically to prevent latency issues
    public void sendTuplesToRemoteWorker(HashMap<Integer, ArrayList<TaskMessage>> packets, long seqId, boolean batchEnd) {
        drainer.add(packets);
        if (batchEnd) {
            ReentrantReadWriteLock.ReadLock readLock = endpointSocketLock.readLock();
            try {
                readLock.lock();
                drainer.send(cachedTaskToNodePort.get(), cachedNodeToPortSocket.get());
            } finally {
                readLock.unlock();
            }
            drainer.clear();
        }
    }

    private void assertCanSerialize(KryoTupleSerializer serializer, List<AddressedTuple> tuples) {
        // Check that all of the tuples can be serialized by serializing them
        for (AddressedTuple addressedTuple : tuples) {
            serializer.serialize(addressedTuple.getTuple());
        }
    }

    public WorkerTopologyContext getWorkerTopologyContext() {
        try {
            String codeDir = ConfigUtils.supervisorStormResourcesPath(ConfigUtils.supervisorStormDistRoot(conf, topologyId));
            String pidDir = ConfigUtils.workerPidsRoot(conf, topologyId);
            return new WorkerTopologyContext(systemTopology, topologyConf, taskToComponent, componentToSortedTasks,
                componentToStreamToFields, topologyId, codeDir, pidDir, port, taskIds,
                defaultSharedResources,
                userSharedResources, cachedTaskToNodePort, assignmentId);
        } catch (IOException e) {
            throw Utils.wrapInRuntime(e);
        }
    }

    public void runWorkerStartHooks() {
        WorkerTopologyContext workerContext = getWorkerTopologyContext();
        if (topology.is_set_worker_hooks()) {
            for (ByteBuffer hook : topology.get_worker_hooks()) {
                byte[] hookBytes = Utils.toByteArray(hook);
                BaseWorkerHook hookObject = Utils.javaDeserialize(hookBytes, BaseWorkerHook.class);
                hookObject.start(topologyConf, workerContext);
            }
        }
    }

    public void runWorkerShutdownHooks() {
        if (topology.is_set_worker_hooks()) {
            for (ByteBuffer hook : topology.get_worker_hooks()) {
                byte[] hookBytes = Utils.toByteArray(hook);
                BaseWorkerHook hookObject = Utils.javaDeserialize(hookBytes, BaseWorkerHook.class);
                hookObject.shutdown();
            }
        }
    }

    public void closeResources() {
        LOG.info("Shutting down default resources");
        ((ExecutorService) defaultSharedResources.get(WorkerTopologyContext.SHARED_EXECUTOR)).shutdownNow();
        LOG.info("Shut down default resources");
    }

    public boolean areAllConnectionsReady() {
        return cachedNodeToPortSocket.get().values()
            .stream()
            .map(WorkerState::isConnectionReady)
            .reduce((left, right) -> left && right)
            .orElse(true);
    }

    public static boolean isConnectionReady(IConnection connection) {
        return !(connection instanceof ConnectionWithStatus)
            || ((ConnectionWithStatus) connection).status() == ConnectionWithStatus.Status.Ready;
    }

    private List<List<Long>> readWorkerExecutors(IStormClusterState stormClusterState, String topologyId, String assignmentId,
        int port) {
        LOG.info("Reading assignments");
        List<List<Long>> executorsAssignedToThisWorker = new ArrayList<>();
        executorsAssignedToThisWorker.add(Constants.SYSTEM_EXECUTOR_ID);
        Map<List<Long>, NodeInfo> executorToNodePort =
            stormClusterState.assignmentInfo(topologyId, null).get_executor_node_port();
        for (Map.Entry<List<Long>, NodeInfo> entry : executorToNodePort.entrySet()) {
            NodeInfo nodeInfo = entry.getValue();
            if (nodeInfo.get_node().equals(assignmentId) && nodeInfo.get_port().iterator().next() == port) {
                executorsAssignedToThisWorker.add(entry.getKey());
            }
        }
        return executorsAssignedToThisWorker;
    }

    private Map<List<Long>, DisruptorQueue> mkReceiveQueueMap(Map<String, Object> topologyConf, Set<List<Long>> executors) {
        Map<List<Long>, DisruptorQueue> receiveQueueMap = new HashMap<>();
        for (List<Long> executor : executors) {
            receiveQueueMap.put(executor, new DisruptorQueue("receive-queue",
                ObjectReader.getInt(topologyConf.get(Config.TOPOLOGY_EXECUTOR_RECEIVE_BUFFER_SIZE)),
                (long) topologyConf.get(Config.TOPOLOGY_DISRUPTOR_WAIT_TIMEOUT_MILLIS),
                ObjectReader.getInt(topologyConf.get(Config.TOPOLOGY_DISRUPTOR_BATCH_SIZE)),
                (long) topologyConf.get(Config.TOPOLOGY_DISRUPTOR_BATCH_TIMEOUT_MILLIS)));
        }
        return receiveQueueMap;
    }

    private Map<String, Object> makeDefaultResources() {
        int threadPoolSize = ObjectReader.getInt(conf.get(Config.TOPOLOGY_WORKER_SHARED_THREAD_POOL_SIZE));
        return ImmutableMap.of(WorkerTopologyContext.SHARED_EXECUTOR, Executors.newFixedThreadPool(threadPoolSize));
    }

    private Map<String, Object> makeUserResources() {
        /* TODO: need to invoke a hook provided by the topology, giving it a chance to create user resources.
        * this would be part of the initialization hook
        * need to separate workertopologycontext into WorkerContext and WorkerUserContext.
        * actually just do it via interfaces. just need to make sure to hide setResource from tasks
        */
        return new HashMap<>();
    }

    private StormTimer mkHaltingTimer(String name) {
        return new StormTimer(name, (thread, exception) -> {
            LOG.error("Error when processing event", exception);
            Utils.exitProcess(20, "Error when processing an event");
        });
    }

    /**
     *
     * @return seq of task ids that receive messages from this worker
     */
    private Set<Integer> workerOutboundTasks() {
        WorkerTopologyContext context = getWorkerTopologyContext();
        Set<String> components = new HashSet<>();
        for (Integer taskId : taskIds) {
            for (Map<String, Grouping> value : context.getTargets(context.getComponentId(taskId)).values()) {
                components.addAll(value.keySet());
            }
        }

        Set<Integer> outboundTasks = new HashSet<>();

        for (Map.Entry<String, List<Integer>> entry : Utils.reverseMap(taskToComponent).entrySet()) {
            if (components.contains(entry.getKey())) {
                outboundTasks.addAll(entry.getValue());
            }
        }
        return outboundTasks;
    }

    public interface ILocalTransferCallback {
        void transfer(List<AddressedTuple> tupleBatch);
    }
}


text:
using ASC.Web.Projects.Resources;
using ASC.Web.Studio.Utility;

namespace ASC.Web.Projects
{
    public partial class TimeTracking : BasePage
    {
        protected override bool CheckSecurity { get { return !Participant.IsVisitor; } }

        protected override void PageLoad()
        {
            Title = HeaderStringHelper.GetPageTitle(ProjectsCommonResource.TimeTracking);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE HTML>

<title>org.robolectric.internal.dependency Class Hierarchy</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="tree: package: org.robolectric.internal.dependency">
<meta name="generator" content="javadoc/PackageTreeWriter">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../script-dir/jquery-ui.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Robolectric 4.9 |

SEARCH:
<input type="text" id="search" value="search" disabled="disabled">
<input type="reset" id="reset" value="reset" disabled="disabled">

Hierarchy For Package org.robolectric.internal.dependency

Package Hierarchies:

All Packages

Class Hierarchy

java.lang.Object

org.robolectric.internal.dependency.DependencyJar

org.robolectric.internal.dependency.LocalDependencyResolver (implements org.robolectric.internal.dependency.DependencyResolver)

org.robolectric.internal.dependency.MavenArtifactFetcher

org.robolectric.internal.dependency.MavenDependencyResolver (implements org.robolectric.internal.dependency.DependencyResolver)

org.robolectric.internal.dependency.MavenJarArtifact

org.robolectric.internal.dependency.PropertiesDependencyResolver (implements org.robolectric.internal.dependency.DependencyResolver)

Interface Hierarchy

org.robolectric.internal.dependency.DependencyResolver

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Robolectric 4.9 |


text:
// We need this lint rule for now because these are only dev-dependencies
/* eslint-disable import/no-extraneous-dependencies */
/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import '@testing-library/jest-dom';
import axios from 'axios';
import { setLogger } from 'react-query';

// eslint-disable-next-line import/no-extraneous-dependencies
import moment from 'moment-timezone';

axios.defaults.adapter = require('axios/lib/adapters/http');

axios.interceptors.response.use(
  (res) => res.data || res,
);

setLogger({
  log: console.log,
  warn: console.warn,
  // ✅ no more errors on the console
  error: () => {},
});

// Mock global objects we use across the app
global.stateColors = {
  deferred: 'mediumpurple',
  failed: 'red',
  queued: 'gray',
  removed: 'lightgrey',
  restarting: 'violet',
  running: 'lime',
  scheduled: 'tan',
  shutdown: 'blue',
  skipped: 'hotpink',
  success: 'green',
  up_for_reschedule: 'turquoise',
  up_for_retry: 'gold',
  upstream_failed: 'orange',
};

global.defaultDagRunDisplayNumber = 245;

global.moment = moment;


text:
package ru.retverd.jira.time.selfcontrol.helpers;

import java.io.PrintWriter;

public class AggrForComponent {
	private int minutesSpent;

	public AggrForComponent() {
		this.minutesSpent = 0;
	}

	public int getMinutesSpent() {
		return minutesSpent;
	}

	public void addMinutesSpent(int minutesSpent) {
		this.minutesSpent += minutesSpent;
	}

	public void saveAggrComponentReport(PrintWriter writer) {
		writer.format("; Hours spent: %.2f%n", ((double) minutesSpent / 60));
	}
}


text:
"""

You are given an array of people, people, which are the attributes of some people in a queue (not necessarily in order). Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki other people in front who have a height greater than or equal to hi.
Reconstruct and return the queue that is represented by the input array people. The returned queue should be formatted as an array queue, where queue[j] = [hj, kj] is the attributes of the jth person in the queue (queue[0] is the person at the front of the queue).

Example 1:

Input: people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
Output: [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
Explanation:
Person 0 has height 5 with no other people taller or the same height in front.
Person 1 has height 7 with no other people taller or the same height in front.
Person 2 has height 5 with two persons taller or the same height in front, which is person 0 and 1.
Person 3 has height 6 with one person taller or the same height in front, which is person 1.
Person 4 has height 4 with four people taller or the same height in front, which are people 0, 1, 2, and 3.
Person 5 has height 7 with one person taller or the same height in front, which is person 1.
Hence [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] is the reconstructed queue.

Example 2:

Input: people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
Output: [[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

Constraints:

1 <= people.length <= 2000
0 <= hi <= 106
0 <= ki < people.length
It is guaranteed that the queue can be reconstructed.

"""

class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort()
        ret = [None for _ in range(len(people))]
        for p in people:
            h, k = p
            idx = 0
            while k >= 0:
                if ret[idx] is None:
                    k -= 1
                elif ret[idx][0] >= h:
                    k -= 1
                idx += 1
            ret[idx - 1] = p
        return ret


text:
import asyncio
import datetime
import unittest
from unittest import mock
from aiohttp import hdrs
from aiohttp.multidict import CIMultiDict
from aiohttp.web import ContentCoding, Request, StreamResponse, Response
from aiohttp.protocol import HttpVersion, HttpVersion11, HttpVersion10
from aiohttp.protocol import RawRequestMessage

class TestStreamResponse(unittest.TestCase):

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

    def tearDown(self):
        self.loop.close()

    def make_request(self, method, path, headers=CIMultiDict(),
                     version=HttpVersion11):
        message = RawRequestMessage(method, path, version, headers,
                                    False, False)
        return self.request_from_message(message)

    def request_from_message(self, message):
        self.app = mock.Mock()
        self.payload = mock.Mock()
        self.transport = mock.Mock()
        self.reader = mock.Mock()
        self.writer = mock.Mock()
        req = Request(self.app, message, self.payload,
                      self.transport, self.reader, self.writer)
        return req

    def test_ctor(self):
        resp = StreamResponse()
        self.assertEqual(200, resp.status)
        self.assertIsNone(resp.keep_alive)

    def test_content_length(self):
        resp = StreamResponse()
        self.assertIsNone(resp.content_length)

    def test_content_length_setter(self):
        resp = StreamResponse()

        resp.content_length = 234
        self.assertEqual(234, resp.content_length)

    def test_drop_content_length_header_on_setting_len_to_None(self):
        resp = StreamResponse()

        resp.content_length = 1
        self.assertEqual("1", resp.headers['Content-Length'])
        resp.content_length = None
        self.assertNotIn('Content-Length', resp.headers)

    def test_set_content_length_to_None_on_non_set(self):
        resp = StreamResponse()

        resp.content_length = None
        self.assertNotIn('Content-Length', resp.headers)
        resp.content_length = None
        self.assertNotIn('Content-Length', resp.headers)

    def test_setting_content_type(self):
        resp = StreamResponse()

        resp.content_type = 'text/html'
        self.assertEqual('text/html', resp.headers['content-type'])

    def test_setting_charset(self):
        resp = StreamResponse()

        resp.content_type = 'text/html'
        resp.charset = 'koi8-r'
        self.assertEqual('text/html; charset=koi8-r',
                         resp.headers['content-type'])

    def test_default_charset(self):
        resp = StreamResponse()

        self.assertIsNone(resp.charset)

    def test_reset_charset(self):
        resp = StreamResponse()

        resp.content_type = 'text/html'
        resp.charset = None
        self.assertIsNone(resp.charset)

    def test_reset_charset_after_setting(self):
        resp = StreamResponse()

        resp.content_type = 'text/html'
        resp.charset = 'koi8-r'
        resp.charset = None
        self.assertIsNone(resp.charset)

    def test_charset_without_content_type(self):
        resp = StreamResponse()

        with self.assertRaises(RuntimeError):
            resp.charset = 'koi8-r'

    def test_last_modified_initial(self):
        resp = StreamResponse()
        self.assertIsNone(resp.last_modified)

    def test_last_modified_string(self):
        resp = StreamResponse()

        dt = datetime.datetime(1990, 1, 2, 3, 4, 5, 0, datetime.timezone.utc)
        resp.last_modified = 'Mon, 2 Jan 1990 03:04:05 GMT'
        self.assertEqual(resp.last_modified, dt)

    def test_last_modified_timestamp(self):
        resp = StreamResponse()

        dt = datetime.datetime(1970, 1, 1, 0, 0, 0, 0, datetime.timezone.utc)

        resp.last_modified = 0
        self.assertEqual(resp.last_modified, dt)

        resp.last_modified = 0.0
        self.assertEqual(resp.last_modified, dt)

    def test_last_modified_datetime(self):
        resp = StreamResponse()

        dt = datetime.datetime(2001, 2, 3, 4, 5, 6, 0, datetime.timezone.utc)
        resp.last_modified = dt
        self.assertEqual(resp.last_modified, dt)

    def test_last_modified_reset(self):
        resp = StreamResponse()

        resp.last_modified = 0
        resp.last_modified = None
        self.assertEqual(resp.last_modified, None)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_start(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        self.assertIsNone(resp.keep_alive)

        msg = resp.start(req)

        self.assertTrue(msg.send_headers.called)
        self.assertIs(msg, resp.start(req))

        self.assertTrue(resp.keep_alive)

        req2 = self.make_request('GET', '/')
        with self.assertRaises(RuntimeError):
            resp.start(req2)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_chunked_encoding(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        self.assertFalse(resp.chunked)

        resp.enable_chunked_encoding()
        self.assertTrue(resp.chunked)

        msg = resp.start(req)
        self.assertTrue(msg.chunked)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_chunk_size(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        self.assertFalse(resp.chunked)

        resp.enable_chunked_encoding(chunk_size=8192)
        self.assertTrue(resp.chunked)

        msg = resp.start(req)
        self.assertTrue(msg.chunked)
        msg.add_chunking_filter.assert_called_with(8192)
        self.assertIsNotNone(msg.filter)

    def test_chunked_encoding_forbidden_for_http_10(self):
        req = self.make_request('GET', '/', version=HttpVersion10)
        resp = StreamResponse()
        resp.enable_chunked_encoding()

        with self.assertRaisesRegex(
                RuntimeError,
                "Using chunked encoding is forbidden for HTTP/1.0"):
            resp.start(req)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_compression_no_accept(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        self.assertFalse(resp.chunked)

        self.assertFalse(resp.compression)
        resp.enable_compression()
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        self.assertFalse(msg.add_compression_filter.called)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_no_accept_backwards_compat(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        self.assertFalse(resp.chunked)

        self.assertFalse(resp.compression)
        resp.enable_compression(force=True)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        self.assertTrue(msg.add_compression_filter.called)
        self.assertIsNotNone(msg.filter)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_false_backwards_compat(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()

        self.assertFalse(resp.compression)
        resp.enable_compression(force=False)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        self.assertFalse(msg.add_compression_filter.called)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_compression_default_coding(self, ResponseImpl):
        req = self.make_request(
            'GET', '/',
            headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'}))
        resp = StreamResponse()
        self.assertFalse(resp.chunked)

        self.assertFalse(resp.compression)
        resp.enable_compression()
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        msg.add_compression_filter.assert_called_with('deflate')
        self.assertEqual('deflate', resp.headers.get(hdrs.CONTENT_ENCODING))
        self.assertIsNotNone(msg.filter)

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_deflate(self, ResponseImpl):
        req = self.make_request(
            'GET', '/',
            headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'}))
        resp = StreamResponse()

        resp.enable_compression(ContentCoding.deflate)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        msg.add_compression_filter.assert_called_with('deflate')
        self.assertEqual('deflate', resp.headers.get(hdrs.CONTENT_ENCODING))

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_no_accept_deflate(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()

        resp.enable_compression(ContentCoding.deflate)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        msg.add_compression_filter.assert_called_with('deflate')
        self.assertEqual('deflate', resp.headers.get(hdrs.CONTENT_ENCODING))

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_gzip(self, ResponseImpl):
        req = self.make_request(
            'GET', '/',
            headers=CIMultiDict({hdrs.ACCEPT_ENCODING: 'gzip, deflate'}))
        resp = StreamResponse()

        resp.enable_compression(ContentCoding.gzip)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        msg.add_compression_filter.assert_called_with('gzip')
        self.assertEqual('gzip', resp.headers.get(hdrs.CONTENT_ENCODING))

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_force_compression_no_accept_gzip(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = StreamResponse()

        resp.enable_compression(ContentCoding.gzip)
        self.assertTrue(resp.compression)

        msg = resp.start(req)
        msg.add_compression_filter.assert_called_with('gzip')
        self.assertEqual('gzip', resp.headers.get(hdrs.CONTENT_ENCODING))

    @mock.patch('aiohttp.web_reqrep.ResponseImpl')
    def test_delete_content_length_if_compression_enabled(self, ResponseImpl):
        req = self.make_request('GET', '/')
        resp = Response(body=b'answer')
        self.assertEqual(6, resp.content_length)

        resp.enable_compression(ContentCoding.gzip)

        resp.start(req)
        self.assertIsNone(resp.content_length)

    def test_write_non_byteish(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))

        with self.assertRaises(AssertionError):
            resp.write(123)

    def test_write_before_start(self):
        resp = StreamResponse()

        with self.assertRaises(RuntimeError):
            resp.write(b'data')

    def test_cannot_write_after_eof(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))

        resp.write(b'data')
        self.writer.drain.return_value = ()
        self.loop.run_until_complete(resp.write_eof())
        self.writer.write.reset_mock()

        with self.assertRaises(RuntimeError):
            resp.write(b'next data')
        self.assertFalse(self.writer.write.called)

    def test_cannot_write_eof_before_headers(self):
        resp = StreamResponse()

        with self.assertRaises(RuntimeError):
            self.loop.run_until_complete(resp.write_eof())

    def test_cannot_write_eof_twice(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))

        resp.write(b'data')
        self.writer.drain.return_value = ()
        self.loop.run_until_complete(resp.write_eof())
        self.assertTrue(self.writer.write.called)

        self.writer.write.reset_mock()
        self.loop.run_until_complete(resp.write_eof())
        self.assertFalse(self.writer.write.called)

    def test_write_returns_drain(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))

        self.assertEqual((), resp.write(b'data'))

    def test_write_returns_empty_tuple_on_empty_data(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))

        self.assertEqual((), resp.write(b''))

    def test_force_close(self):
        resp = StreamResponse()

        self.assertIsNone(resp.keep_alive)
        resp.force_close()
        self.assertFalse(resp.keep_alive)

    def test_response_cookies(self):
        resp = StreamResponse()

        self.assertEqual(resp.cookies, {})
        self.assertEqual(str(resp.cookies), '')

        resp.set_cookie('name', 'value')
        self.assertEqual(str(resp.cookies), 'Set-Cookie: name=value; Path=/')
        resp.set_cookie('name', 'other_value')
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=other_value; Path=/')

        resp.cookies['name'] = 'another_other_value'
        resp.cookies['name']['max-age'] = 10
        self.assertEqual(
            str(resp.cookies),
            'Set-Cookie: name=another_other_value; Max-Age=10; Path=/')

        resp.del_cookie('name')
        self.assertEqual(
            str(resp.cookies),
            'Set-Cookie: name=; Max-Age=0; Path=/')

        resp.set_cookie('name', 'value', domain='local.host', path=None)
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=value; Domain=local.host')

    def test_response_cookie_path(self):
        resp = StreamResponse()

        self.assertEqual(resp.cookies, {})

        resp.set_cookie('name', 'value', path='/some/path')
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=value; Path=/some/path')
        resp.set_cookie('name', 'value', expires='123')
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=value; expires=123;'
                         ' Path=/')
        resp.set_cookie('name', 'value', domain='example.com',
                        path='/home', expires='123', max_age='10',
                        secure=True, httponly=True, version='2.0')
        self.assertEqual(str(resp.cookies).lower(),
                         'set-cookie: name=value; '
                         'domain=example.com; '
                         'expires=123; '
                         'httponly; '
                         'max-age=10; '
                         'path=/home; '
                         'secure; '
                         'version=2.0')

    def test_response_cookie__issue_del_cookie(self):
        resp = StreamResponse()

        self.assertEqual(resp.cookies, {})
        self.assertEqual(str(resp.cookies), '')

        resp.del_cookie('name')
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=; Max-Age=0; Path=/')

    def test_cookie_set_after_del(self):
        resp = StreamResponse()

        resp.del_cookie('name')
        resp.set_cookie('name', 'val')
        # check for Max-Age dropped
        self.assertEqual(str(resp.cookies),
                         'Set-Cookie: name=val; Path=/')

    def test_set_status_with_reason(self):
        resp = StreamResponse()

        resp.set_status(200, "Everithing is fine!")
        self.assertEqual(200, resp.status)
        self.assertEqual("Everithing is fine!", resp.reason)

    def test_start_force_close(self):
        req = self.make_request('GET', '/')
        resp = StreamResponse()
        resp.force_close()
        self.assertFalse(resp.keep_alive)

        msg = resp.start(req)
        self.assertFalse(resp.keep_alive)
        self.assertTrue(msg.closing)

    def test___repr__(self):
        req = self.make_request('GET', '/path/to')
        resp = StreamResponse(reason=301)
        resp.start(req)
        self.assertEqual("<StreamResponse 301 GET /path/to >", repr(resp))

    def test___repr__not_started(self):
        resp = StreamResponse(reason=301)
        self.assertEqual("<StreamResponse 301 not started>", repr(resp))

    def test_keep_alive_http10(self):
        message = RawRequestMessage('GET', '/', HttpVersion10, CIMultiDict(),
                                    True, False)
        req = self.request_from_message(message)
        resp = StreamResponse()
        resp.start(req)
        self.assertFalse(resp.keep_alive)

        headers = CIMultiDict(Connection='keep-alive')
        message = RawRequestMessage('GET', '/', HttpVersion10, headers,
                                    False, False)
        req = self.request_from_message(message)
        resp = StreamResponse()
        resp.start(req)
        self.assertEqual(resp.keep_alive, True)

    def test_keep_alive_http09(self):
        headers = CIMultiDict(Connection='keep-alive')
        message = RawRequestMessage('GET', '/', HttpVersion(0, 9), headers,
                                    False, False)
        req = self.request_from_message(message)
        resp = StreamResponse()
        resp.start(req)
        self.assertFalse(resp.keep_alive)

class TestResponse(unittest.TestCase):

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

    def tearDown(self):
        self.loop.close()

    def make_request(self, method, path, headers=CIMultiDict()):
        self.app = mock.Mock()
        message = RawRequestMessage(method, path, HttpVersion11, headers,
                                    False, False)
        self.payload = mock.Mock()
        self.transport = mock.Mock()
        self.reader = mock.Mock()
        self.writer = mock.Mock()
        req = Request(self.app, message, self.payload,
                      self.transport, self.reader, self.writer)
        return req

    def test_ctor(self):
        resp = Response()

        self.assertEqual(200, resp.status)
        self.assertEqual('OK', resp.reason)
        self.assertIsNone(resp.body)
        self.assertEqual(0, resp.content_length)
        self.assertEqual(CIMultiDict([('CONTENT-LENGTH', '0')]),
                         resp.headers)

    def test_ctor_with_headers_and_status(self):
        resp = Response(body=b'body', status=201, headers={'Age': '12'})

        self.assertEqual(201, resp.status)
        self.assertEqual(b'body', resp.body)
        self.assertEqual(4, resp.content_length)
        self.assertEqual(CIMultiDict(
            [('AGE', '12'),
             ('CONTENT-LENGTH', '4')]), resp.headers)

    def test_ctor_content_type(self):
        resp = Response(content_type='application/json')

        self.assertEqual(200, resp.status)
        self.assertEqual('OK', resp.reason)
        self.assertEqual(
            CIMultiDict(
                [('CONTENT-TYPE', 'application/json'),
                 ('CONTENT-LENGTH', '0')]),
            resp.headers)

    def test_ctor_text_body_combined(self):
        with self.assertRaises(ValueError):
            Response(body=b'123', text='test text')

    def test_ctor_text(self):
        resp = Response(text='test text')

        self.assertEqual(200, resp.status)
        self.assertEqual('OK', resp.reason)
        self.assertEqual(
            CIMultiDict(
                [('CONTENT-TYPE', 'text/plain; charset=utf-8'),
                 ('CONTENT-LENGTH', '9')]),
            resp.headers)

        self.assertEqual(resp.body, b'test text')
        self.assertEqual(resp.text, 'test text')

    def test_assign_nonbyteish_body(self):
        resp = Response(body=b'data')

        with self.assertRaises(TypeError):
            resp.body = 123
        self.assertEqual(b'data', resp.body)
        self.assertEqual(4, resp.content_length)

    def test_assign_nonstr_text(self):
        resp = Response(text='test')

        with self.assertRaises(TypeError):
            resp.text = b'123'
        self.assertEqual(b'test', resp.body)
        self.assertEqual(4, resp.content_length)

    def test_send_headers_for_empty_body(self):
        req = self.make_request('GET', '/')
        resp = Response()

        self.writer.drain.return_value = ()
        buf = b''

        def append(data):
            nonlocal buf
            buf += data

        self.writer.write.side_effect = append

        resp.start(req)
        self.loop.run_until_complete(resp.write_eof())
        txt = buf.decode('utf8')
        self.assertRegex(txt, 'HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n'
                         'CONNECTION: keep-alive\r\n'
                         'DATE: .+\r\nSERVER: .+\r\n\r\n')

    def test_render_with_body(self):
        req = self.make_request('GET', '/')
        resp = Response(body=b'data')

        self.writer.drain.return_value = ()
        buf = b''

        def append(data):
            nonlocal buf
            buf += data

        self.writer.write.side_effect = append

        resp.start(req)
        self.loop.run_until_complete(resp.write_eof())
        txt = buf.decode('utf8')
        self.assertRegex(txt, 'HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 4\r\n'
                         'CONNECTION: keep-alive\r\n'
                         'DATE: .+\r\nSERVER: .+\r\n\r\ndata')

    def test_send_set_cookie_header(self):
        resp = Response()
        resp.cookies['name'] = 'value'

        req = self.make_request('GET', '/')
        self.writer.drain.return_value = ()
        buf = b''

        def append(data):
            nonlocal buf
            buf += data

        self.writer.write.side_effect = append

        resp.start(req)
        self.loop.run_until_complete(resp.write_eof())
        txt = buf.decode('utf8')
        self.assertRegex(txt, 'HTTP/1.1 200 OK\r\nCONTENT-LENGTH: 0\r\n'
                         'SET-COOKIE: name=value\r\n'
                         'CONNECTION: keep-alive\r\n'
                         'DATE: .+\r\nSERVER: .+\r\n\r\n')

    def test_set_text_with_content_type(self):
        resp = Response()
        resp.content_type = "text/html"
        resp.text = "text"

        self.assertEqual("text", resp.text)
        self.assertEqual(b"text", resp.body)
        self.assertEqual("text/html", resp.content_type)

    def test_set_text_with_charset(self):
        resp = Response()
        resp.content_type = 'text/plain'
        resp.charset = "KOI8-R"
        resp.text = "текст"

        self.assertEqual("текст", resp.text)
        self.assertEqual("текст".encode('koi8-r'), resp.body)
        self.assertEqual("koi8-r", resp.charset)

    def test_started_when_not_started(self):
        resp = StreamResponse()
        self.assertFalse(resp.started)

    def test_started_when_started(self):
        resp = StreamResponse()
        resp.start(self.make_request('GET', '/'))
        self.assertTrue(resp.started)

    def test_drain_before_start(self):

        @asyncio.coroutine
        def go():
            resp = StreamResponse()
            with self.assertRaises(RuntimeError):
                yield from resp.drain()

        self.loop.run_until_complete(go())

    def test_nonstr_text_in_ctor(self):
        with self.assertRaises(TypeError):
            Response(text=b'data')

    def test_text_in_ctor_with_content_type(self):
        resp = Response(text='data', content_type='text/html')
        self.assertEqual('data', resp.text)
        self.assertEqual('text/html', resp.content_type)

    def test_text_in_ctor_with_content_type_header(self):
        resp = Response(text='текст',
                        headers={'Content-Type': 'text/html; charset=koi8-r'})
        self.assertEqual('текст'.encode('koi8-r'), resp.body)
        self.assertEqual('text/html', resp.content_type)
        self.assertEqual('koi8-r', resp.charset)

    def test_text_with_empty_payload(self):
        resp = Response(status=200)
        self.assertEqual(resp.body, None)
        self.assertEqual(resp.text, None)


text:
SOURCES=ModMain.cs  SunControlGUI.cs  SunController.cs  TimeSlider.cs  UIUtils.cs Language.cs

TimeWarpMod.dll: ${SOURCES}
	mcs -out:TimeWarpMod.dll -target:library -r:ColossalManaged.dll -r:ICities.dll -r:Assembly-CSharp.dll -r:UnityEngine.dll -codepage:utf8 ${SOURCES}


text:
                          {{thisCustomer.CompanyName}}{{thisCustomer.CompanyNameCN}}

                          {{thisCustomer.ContactName}}{{thisCustomer.CompanyTitle}}

                          {{thisCustomer.Phone}}

                          {{thisCustomer.Email}}

产品销售记录

                            <input type="text" class="form-control" placeholder="搜索..." ng-model='searchText.$'>

                            <button type="button" class="btn btn-info" data-toggle="collapse" data-target="#demo">高级搜索</button>

                                <input type="text" class="form-control" placeholder="询价单号" ng-model='searchText.product_details.EnquiryNum'>

                                <input type="text" class="form-control" placeholder="亿仟SAP" ng-model='searchText.product_details.YiQianSAP'>

                                <input type="text" class="form-control" placeholder="供应商SAP" ng-model='searchText.product_details.CustomerSAP'>

                                <input type="text" class="form-control" placeholder="供应商零件号" ng-model='searchText.product_details.CustomerPartNumber'>

                                <input type="text" class="form-control" placeholder="备注号" ng-model='searchText.product_details.ReferenceNum'>

                                <input type="text" class="form-control" placeholder="供应商代码" ng-model='searchText.product_details.CustomerCode'>

                        <labe>重量区间</labe>

<input type="text" class="form-control" placeholder="0KG" ng-model='searchText.product_details.WeightStart'>

<input type="text" class="form-control" placeholder="1000KG" ng-model='searchText.product_details.WeightEnd'>

                        <labe>进货时间</labe>

<input type="text" class="form-control" placeholder="日/月/年(起)" ng-model='searchText.product_details.OrderTimeStart'>

<input type="text" class="form-control" placeholder="日/月/年(止)" ng-model='searchText.product_details.OrderTimeEnd'>

                        <labe>价格区间</labe>

<input type="text" class="form-control" placeholder="0元" ng-model='searchText.product_details.PriceStart'>

<input type="text" class="form-control" placeholder="100000000元" ng-model='searchText.product_details.PriceEnd'>

                    {{searchText}}

                                Code
                                Product Name
                                Product Name CN
                                YiQianPartNum
                                Categories

                                {{Product.id}}
                                {{Product.ProductName}}
                                {{Product.ProductNameCN}}
                                {{Product.YiQianPartNumber}}
                                {{Product.CategoryID}}

                                询价单号
                                亿仟SAP
                                供应商SAP
                                供应商零件号
                                参考零件单号
                                价格(USD)
                                价格(CNY)
                                供应商
                                进货日期
                                已停产
                                备注

                                {{Productsdetail.EnquiryNum}}
                                {{Productsdetail.YiQianSAP}}
                                {{Productsdetail.CustomerSAP}}
                                {{Productsdetail.CustomerPartNumber}}
                                {{Productsdetail.ReferenceNum}}
                                {{Productsdetail.UnitPriceUSD}}
                                {{Productsdetail.UnitPriceCNY}}
                                {{Productsdetail.CustomerCode}}
                                {{Productsdetail.Ordertime}}
                                {{Productsdetail.Discountinued}}
                                {{Productsdetail.Comment}}

                    {{CustomerRecord}}


text:
#include "laszipper.hpp"

#include <string.h>
#include <stdlib.h>

#include "bytestreamout_file.hpp"
#include "bytestreamout_ostream.hpp"
#include "laswritepoint.hpp"

bool LASzipper::open(FILE* outfile, const LASzip* laszip)
{
  if (!outfile) return return_error("FILE* outfile pointer is NULL");
  if (!laszip) return return_error("const LASzip* laszip pointer is NULL");
  count = 0;
  if (writer) delete writer;
  writer = new LASwritePoint();
  if (!writer) return return_error("alloc of LASwritePoint failed");
  if (!writer->setup(laszip->num_items, laszip->items, laszip)) return return_error("setup() of LASwritePoint failed");
  if (stream) delete stream;
  if (IS_LITTLE_ENDIAN())
    stream = new ByteStreamOutFileLE(outfile);
  else
    stream = new ByteStreamOutFileBE(outfile);
  if (!stream) return return_error("alloc of ByteStreamOutFile failed");
  if (!writer->init(stream)) return return_error("init() of LASwritePoint failed");
  return true;
}

bool LASzipper::open(ostream& outstream, const LASzip* laszip)
{
  if (!laszip) return return_error("const LASzip* laszip pointer is NULL");
  count = 0;
  if (writer) delete writer;
  writer = new LASwritePoint();
  if (!writer) return return_error("alloc of LASwritePoint failed");
  if (!writer->setup(laszip->num_items, laszip->items, laszip)) return return_error("setup() of LASwritePoint failed");
  if (stream) delete stream;
  if (IS_LITTLE_ENDIAN())
    stream = new ByteStreamOutOstreamLE(outstream);
  else
    stream = new ByteStreamOutOstreamBE(outstream);
  if (!stream) return return_error("alloc of ByteStreamOutStream failed");
  if (!writer->init(stream)) return return_error("init() of LASwritePoint failed");
  return true;
}

bool LASzipper::write(const unsigned char * const * point)
{
  count++;
  return (writer->write(point) == TRUE);
}

bool LASzipper::chunk()
{
  if (!writer->chunk()) return return_error("chunk() of LASwritePoint failed");
  return true;
}

bool LASzipper::close()
{
  BOOL done = TRUE;
  if (writer)
  {
    done = writer->done();
    delete writer;
    writer = 0;
  }
  if (stream)
  {
    delete stream;
    stream = 0;
  }
  if (!done) return return_error("done() of LASwritePoint failed");
  return true;
}

const char* LASzipper::get_error() const
{
  return error_string;
}

bool LASzipper::return_error(const char* error)
{
  char err[256];
  sprintf(err, "%s (LASzip v%d.%dr%d)", error, LASZIP_VERSION_MAJOR, LASZIP_VERSION_MINOR, LASZIP_VERSION_REVISION);
  if (error_string) free(error_string);
  error_string = LASCopyString(err);
  return false;
}

LASzipper::LASzipper()
{
  error_string = 0;
  count = 0;
  stream = 0;
  writer = 0;
}

LASzipper::~LASzipper()
{
  if (error_string) free(error_string);
  if (writer || stream) close();
}


text:
require('controllers/HeaderController.js');

require('controllers/ApplicationController.js');

require('controllers/SlidesController.js');

require('controllers/SlideController.js');

require('controllers/SlidethumbnailsController.js');

require('models/Slide.js');

require('views/SlideTextField.js');

require('views/ApplicationView.js');

require('views/SlidesView.js');

require('views/SlidedetailView.js');

require('views/SlideThumbnailView.js');

require('views/SlidesthumbnailsView.js');

App.Router.map(function() {
  this.resource("slides");
  return this.resource("slide", {
    path: 'slides/:slide_id'
  });
});

App.ApplicationRoute = Ember.Route.extend({
  setupController: function() {
    return this.controllerFor('slides').set('content', App.Slide.find());
  },
  events: {
    updateActiveSlide: function(newSlide) {
      var slidesCon;

      slidesCon = this.controllerFor('slides');
      slidesCon.set('activeSlideIndex', newSlide.get('position'));
      return this.transitionTo('slide', slidesCon.get('activeSlide'));
    }
  }
});

App.IndexRoute = Ember.Route.extend({
  redirect: function() {
    return this.replaceWith('slides');
  }
});

App.SlidesRoute = Ember.Route.extend({
  events: {
    transitionAfterDeletion: function() {}
  },
  setupController: function(controller) {
    return controller.set('content', App.Slide.find());
  },
  renderTemplate: function(controller) {
    this.render("slides", {
      into: 'application',
      outlet: 'slides',
      controller: controller
    });
    this.render("rightbar", {
      into: 'application',
      outlet: 'rightbar',
      controller: "slides"
    });
    return this.render("maincontrols", {
      into: 'application',
      outlet: 'controls',
      controller: controller
    });
  }
});

App.SlideRoute = Ember.Route.extend({
  events: {
    transitionAfterDeletion: function(pos) {
      var slideAtPos;

      slideAtPos = this.controllerFor('slides').get('arrangedContent').objectAt(pos);
      if (slideAtPos != null) {
        return this.replaceWith("slide", slideAtPos);
      } else {
        return this.replaceWith("slides");
      }
    }
  },
  renderTemplate: function(controller) {
    this.render("showcontrols", {
      into: 'application',
      outlet: 'controls',
      controller: 'slides'
    });
    this.render("slidedetail", {
      into: 'application',
      outlet: 'slides',
      controller: controller
    });
    return this.render("rightbar", {
      into: 'application',
      outlet: 'rightbar',
      controller: "slides"
    });
  }
});


text:
require 'net/ssh'
require 'net/scp'
require 'uri'
require 'rainbow/refinement'
require 'fog'
module AvstCloud
end


text:
namespace google {
namespace cloud {
namespace servicecontrol {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

QuotaControllerClient::QuotaControllerClient(
    std::shared_ptr<QuotaControllerConnection> connection, Options opts)
    : connection_(std::move(connection)),
      options_(
          internal::MergeOptions(std::move(opts), connection_->options())) {}
QuotaControllerClient::~QuotaControllerClient() = default;

StatusOr<google::api::servicecontrol::v1::AllocateQuotaResponse>
QuotaControllerClient::AllocateQuota(
    google::api::servicecontrol::v1::AllocateQuotaRequest const& request,
    Options opts) {
  internal::OptionsSpan span(internal::MergeOptions(std::move(opts), options_));
  return connection_->AllocateQuota(request);
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace servicecontrol
}  // namespace cloud
}  // namespace google


text:
<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Config_model extends CI_Model {

    //////////////////////////////MODELOS DE PERMISOS DE ROLES

    public function get_roles() {
        $sql_string = "SELECT *
                      FROM umbitems_tipos_usuario";
        $sql_query = $this->db->query($sql_string);
        return $sql_query->result();
    }

    public function get_role($role_id) {
        $sql_string = "SELECT *
                      FROM {$this->db->dbprefix('tipos_usuario')}
                      WHERE ID_TIPO_USU = {$role_id}";
        $sql_query = $this->db->query($sql_string);
        return $sql_query->result();
    }

    public function get_rol_permissions($id_rol, $key = 'ID_MODULO') {
        //DEFINIMOS VARIABLES
        $array_modules = array();
        $array_permissions = array();
        //==>   1) CONSULTAMOS TODOS LOS MODULOS REGISTRADOS
        $sql_string = "SELECT *
                      FROM {$this->db->dbprefix('modulos')}";
        $sql_query = $this->db->query($sql_string);

        foreach ($sql_query->result() as $row) {
            $array_modules[$row->$key]['name'] = $row->NOM_MODULO;
            $array_modules[$row->$key]['id'] = $row->ID_MODULO;
            $array_permissions = array();

            //==>   2) CONSULTAMOS LOS PERMISOS DEL ROL POR CADA MODULO
            $sql_string2 = "SELECT *
                           FROM {$this->db->dbprefix('modulos_tipos')}
                           WHERE
                           ID_MODULO = {$row->ID_MODULO} AND
                           ID_TIPO_USU = {$id_rol}
                           ";
            $sql_query2 = $this->db->query($sql_string2);
            //==>   3) SI NO HAY REGISTROS, A��ADIMOS LOS PERMISOS EN 0
            if ($sql_query2->num_rows() == 0) {
                $sql_insert = "INSERT INTO {$this->db->dbprefix('modulos_tipos')}(
                                   ID_MODULO,  ID_TIPO_USU,    CONSULTAR,
                                   GUARDAR, 	ACTUALIZAR,    ELIMINAR
                                   )VALUES(
                                   {$row->ID_MODULO},  {$id_rol},  0,
                                   0,  0,  0
                                   )";
                $this->db->query($sql_insert);
                $array_permissions['permission_view'] = 0;
                $array_permissions['permission_add'] = 0;
                $array_permissions['permission_edit'] = 0;
                $array_permissions['permission_delete'] = 0;
            } else {
                $data = $sql_query2->result_array();
                $array_permissions['permission_view'] = $data[0]['CONSULTAR'];
                $array_permissions['permission_add'] = $data[0]['GUARDAR'];
                $array_permissions['permission_edit'] = $data[0]['ACTUALIZAR'];
                $array_permissions['permission_delete'] = $data[0]['ELIMINAR'];
            }
            $array_modules[$row->$key]['permissions'] = $array_permissions;
        }
        return $array_modules;
    }

    public function update_roles($data) {
        //==>   1) CONSULTAMOS TODOS LOS MODULOS REGISTRADOS
        $sql_string = "SELECT *
                      FROM {$this->db->dbprefix('modulos')}";
        $sql_query = $this->db->query($sql_string);
        foreach ($sql_query->result() as $row) {
            $permission_view = (isset($data['data']['permission_view_' . $row->ID_MODULO]) && $data['data']['permission_view_' . $row->ID_MODULO] == 1) ? '1' : '0';
            $permission_add = (isset($data['data']['permission_add_' . $row->ID_MODULO]) && $data['data']['permission_add_' . $row->ID_MODULO] == 1) ? '1' : '0';
            $permission_edit = (isset($data['data']['permission_edit_' . $row->ID_MODULO]) && $data['data']['permission_edit_' . $row->ID_MODULO] == 1) ? '1' : '0';
            $permission_delete = (isset($data['data']['permission_delete_' . $row->ID_MODULO]) && $data['data']['permission_delete_' . $row->ID_MODULO] == 1) ? '1' : '0';

            $SQL_string = "UPDATE {$this->db->dbprefix('modulos_tipos')} SET
                           CONSULTAR = '{$permission_view}',
                           GUARDAR = '{$permission_add}',
                           ACTUALIZAR = '{$permission_edit}',
                           ELIMINAR = '{$permission_delete}'
                           WHERE ID_MODULO = '{$row->ID_MODULO}' AND
                           ID_TIPO_USU = '{$data['rol_id']}'";
            //echo $SQL_string.'<br>';
            $this->db->query($SQL_string);
        }
    }

}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace Kimono.Controls.SnackBar
{
    public static class SnackBarAppearance
    {
        public static double Opacity { get; set; } = 0.8;
        public static double MessageFontSize { get; set; } = 12;
        public static Transition Transition { get; set; } = new AddDeleteThemeTransition();
        public static Brush BackgroundBrush { get; set; }
    }
}


text:
A puzzle game for the Oculus Rift

This game was creating during the my first semester at keimyung University.
There was no bounds in this class, we were free to create whatever we wanted.
Since the lab owned an Oculus Rift, we decided to try it and make a game base on it.

Perception uses the Oculus as mush as possible, and most of the puzzle mechanics are based on the use of this device. For example, the direction where the player looks or the way he nods may be required to open a door.

In addition of the Oculus, we had a three color system in the game : when swapping the color, some elements may appear or disappear, or just behave differently.

During the developpement of Perception, we mainly focused on the mechanics and the technical part of the game, and so there is a lack of level design.

Levels are hard to progress through, and a tutorial would have been nice. Yet with a bit of perseverance, it is possible to go through all the levels.


text:
import {expect} from 'chai';
import {spec} from 'modules/teadsBidAdapter.js';
import {newBidder} from 'src/adapters/bidderFactory.js';

const ENDPOINT = 'https://a.teads.tv/hb/bid-request';
const AD_SCRIPT = '<script type="text/javascript" class="teads" async="true" src="https://a.teads.tv/hb/getAdSettings"></script>"';

describe('teadsBidAdapter', () => {
  const adapter = newBidder(spec);

  describe('inherited functions', () => {
    it('exists and is a function', () => {
      expect(adapter.callBids).to.exist.and.to.be.a('function');
    });
  });

  describe('isBidRequestValid', function() {
    let bid = {
      'bidder': 'teads',
      'params': {
        'placementId': 10433394,
        'pageId': 1234
      },
      'adUnitCode': 'adunit-code',
      'sizes': [[300, 250], [300, 600]],
      'bidId': '30b31c1838de1e',
      'bidderRequestId': '22edbae2733bf6',
      'auctionId': '1d1a030790a475',
      'creativeId': 'er2ee'
    };

    it('should return true when required params found', function() {
      expect(spec.isBidRequestValid(bid)).to.equal(true);
    });

    it('should return false when pageId is not valid (letters)', function() {
      let bid = Object.assign({}, bid);
      delete bid.params;
      bid.params = {
        'placementId': 1234,
        'pageId': 'ABCD'
      };

      expect(spec.isBidRequestValid(bid)).to.equal(false);
    });

    it('should return false when placementId is not valid (letters)', function() {
      let bid = Object.assign({}, bid);
      delete bid.params;
      bid.params = {
        'placementId': 'FCP',
        'pageId': 1234
      };

      expect(spec.isBidRequestValid(bid)).to.equal(false);
    });

    it('should return false when placementId < 0 or pageId < 0', function() {
      let bid = Object.assign({}, bid);
      delete bid.params;
      bid.params = {
        'placementId': -1,
        'pageId': -1
      };

      expect(spec.isBidRequestValid(bid)).to.equal(false);
    });

    it('should return false when required params are not passed', function() {
      let bid = Object.assign({}, bid);
      delete bid.params;

      bid.params = {
        'placementId': 0
      };

      expect(spec.isBidRequestValid(bid)).to.equal(false);
    });
  });

  describe('buildRequests', function() {
    let bidRequests = [
      {
        'bidder': 'teads',
        'params': {
          'placementId': 10433394,
          'pageId': 1234
        },
        'adUnitCode': 'adunit-code',
        'sizes': [[300, 250], [300, 600]],
        'bidId': '30b31c1838de1e',
        'bidderRequestId': '22edbae2733bf6',
        'auctionId': '1d1a030790a475',
        'creativeId': 'er2ee',
        'deviceWidth': 1680
      }
    ];

    let bidderResquestDefault = {
      'auctionId': '1d1a030790a475',
      'bidderRequestId': '22edbae2733bf6',
      'timeout': 3000
    };

    it('sends bid request to ENDPOINT via POST', function() {
      const request = spec.buildRequests(bidRequests, bidderResquestDefault);

      expect(request.url).to.equal(ENDPOINT);
      expect(request.method).to.equal('POST');
    });

    it('should send US Privacy to endpoint', function() {
      let usPrivacy = 'OHHHFCP1'
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'uspConsent': usPrivacy
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.us_privacy).to.exist;
      expect(payload.us_privacy).to.equal(usPrivacy);
    });

    it('should send GDPR to endpoint', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': consentString,
          'gdprApplies': true,
          'vendorData': {
            'hasGlobalConsent': false
          },
          'apiVersion': 1
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal(consentString);
      expect(payload.gdpr_iab.status).to.equal(12);
      expect(payload.gdpr_iab.apiVersion).to.equal(1);
    });

    it('should add referer info to payload', function () {
      const bidRequest = Object.assign({}, bidRequests[0])
      const bidderRequest = {
        refererInfo: {
          referer: 'https://example.com/page.html',
          reachedTop: true,
          numIframes: 2
        }
      }
      const request = spec.buildRequests([bidRequest], bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.referrer).to.exist;
      expect(payload.referrer).to.deep.equal('https://example.com/page.html')
    });

    it('should add networkBandwidth info to payload', function () {
      const request = spec.buildRequests(bidRequests, bidderResquestDefault);
      const payload = JSON.parse(request.data);

      const bandwidth = window.navigator && window.navigator.connection && window.navigator.connection.downlink;

      expect(payload.networkBandwidth).to.exist;

      if (bandwidth) {
        expect(payload.networkBandwidth).to.deep.equal(bandwidth.toString());
      } else {
        expect(payload.networkBandwidth).to.deep.equal('');
      }
    });

    it('should add pageReferrer info to payload', function () {
      const request = spec.buildRequests(bidRequests, bidderResquestDefault);
      const payload = JSON.parse(request.data);

      expect(payload.pageReferrer).to.exist;
      expect(payload.pageReferrer).to.deep.equal(document.referrer);
    });

    it('should add timeToFirstByte info to payload', function () {
      const request = spec.buildRequests(bidRequests, bidderResquestDefault);
      const payload = JSON.parse(request.data);
      const performance = window.performance || window.webkitPerformance || window.msPerformance || window.mozPerformance;

      const ttfbExpectedV2 = performance &&
        typeof performance.getEntriesByType === 'function' &&
        Object.prototype.toString.call(performance.getEntriesByType) === '[object Function]' &&
        performance.getEntriesByType('navigation')[0] &&
        performance.getEntriesByType('navigation')[0].responseStart &&
        performance.getEntriesByType('navigation')[0].requestStart &&
        performance.getEntriesByType('navigation')[0].responseStart > 0 &&
        performance.getEntriesByType('navigation')[0].requestStart > 0 &&
        Math.round(
          performance.getEntriesByType('navigation')[0].responseStart - performance.getEntriesByType('navigation')[0].requestStart
        );

      expect(payload.timeToFirstByte).to.exist;

      if (ttfbExpectedV2) {
        expect(payload.timeToFirstByte).to.deep.equal(ttfbExpectedV2.toString());
      } else {
        const ttfbWithTimingV1 = performance &&
            performance.timing.responseStart &&
            performance.timing.requestStart &&
            performance.timing.responseStart > 0 &&
            performance.timing.requestStart > 0 &&
            performance.timing.responseStart - performance.timing.requestStart;
        const ttfbExpectedV1 = ttfbWithTimingV1 ? ttfbWithTimingV1.toString() : '';

        expect(payload.timeToFirstByte).to.deep.equal(ttfbExpectedV1);
      }
    });

    it('should send GDPR to endpoint with 11 status', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': consentString,
          'gdprApplies': true,
          'vendorData': {
            'hasGlobalScope': true
          },
          'apiVersion': 1
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal(consentString);
      expect(payload.gdpr_iab.status).to.equal(11);
      expect(payload.gdpr_iab.apiVersion).to.equal(1);
    });

    it('should send GDPR TCF2 to endpoint with 12 status', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': consentString,
          'gdprApplies': true,
          'vendorData': {
            'isServiceSpecific': true
          },
          'apiVersion': 2
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal(consentString);
      expect(payload.gdpr_iab.status).to.equal(12);
      expect(payload.gdpr_iab.apiVersion).to.equal(2);
    });

    it('should send GDPR to endpoint with 22 status', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': undefined,
          'gdprApplies': undefined,
          'vendorData': undefined,
          'apiVersion': 1
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal('');
      expect(payload.gdpr_iab.status).to.equal(22);
      expect(payload.gdpr_iab.apiVersion).to.equal(1);
    });

    it('should send GDPR to endpoint with 0 status', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': consentString,
          'gdprApplies': false,
          'vendorData': {
            'hasGlobalScope': false
          },
          'apiVersion': 1
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal(consentString);
      expect(payload.gdpr_iab.status).to.equal(0);
      expect(payload.gdpr_iab.apiVersion).to.equal(1);
    });

    it('should send GDPR to endpoint with 0 status when gdprApplies = false (vendorData = undefined)', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': undefined,
          'gdprApplies': false,
          'vendorData': undefined,
          'apiVersion': 1
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal('');
      expect(payload.gdpr_iab.status).to.equal(0);
      expect(payload.gdpr_iab.apiVersion).to.equal(1);
    });

    it('should send GDPR to endpoint with 12 status when apiVersion = 0', function() {
      let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A==';
      let bidderRequest = {
        'auctionId': '1d1a030790a475',
        'bidderRequestId': '22edbae2733bf6',
        'timeout': 3000,
        'gdprConsent': {
          'consentString': consentString,
          'gdprApplies': true,
          'vendorData': {
            'hasGlobalScope': false
          },
          'apiVersion': 0
        }
      };

      const request = spec.buildRequests(bidRequests, bidderRequest);
      const payload = JSON.parse(request.data);

      expect(payload.gdpr_iab).to.exist;
      expect(payload.gdpr_iab.consent).to.equal(consentString);
      expect(payload.gdpr_iab.status).to.equal(12);
      expect(payload.gdpr_iab.apiVersion).to.equal(0);
    });

    it('should use good mediaTypes video playerSizes', function() {
      const mediaTypesPlayerSize = {
        'mediaTypes': {
          'video': {
            'playerSize': [32, 34]
          }
        }
      };
      checkMediaTypesSizes(mediaTypesPlayerSize, '32x34')
    });

    it('should add schain info to payload if available', function () {
      const bidRequest = Object.assign({}, bidRequests[0], {
        schain: {
          ver: '1.0',
          complete: 1,
          nodes: [{
            asi: 'example.com',
            sid: '00001',
            hp: 1
          }]
        }
      });

      const request = spec.buildRequests([bidRequest], bidderResquestDefault);
      const payload = JSON.parse(request.data);

      expect(payload.schain).to.exist;
      expect(payload.schain).to.deep.equal({
        ver: '1.0',
        complete: 1,
        nodes: [{
          asi: 'example.com',
          sid: '00001',
          hp: 1
        }]
      });
    });

    it('should use good mediaTypes video sizes', function() {
      const mediaTypesVideoSizes = {
        'mediaTypes': {
          'video': {
            'sizes': [12, 14]
          }
        }
      };
      checkMediaTypesSizes(mediaTypesVideoSizes, '12x14')
    });

    it('should use good mediaTypes banner sizes', function() {
      const mediaTypesBannerSize = {
        'mediaTypes': {
          'banner': {
            'sizes': [46, 48]
          }
        }
      };
      checkMediaTypesSizes(mediaTypesBannerSize, '46x48')
    });

    it('should use good mediaTypes for both video and banner sizes', function() {
      const hybridMediaTypes = {
        'mediaTypes': {
          'banner': {
            'sizes': [46, 48]
          },
          'video': {
            'sizes': [[50, 34], [45, 45]]
          }
        }
      };
      checkMediaTypesSizes(hybridMediaTypes, ['46x48', '50x34', '45x45'])
    });

    function checkMediaTypesSizes(mediaTypes, expectedSizes) {
      const bidRequestWithBannerSizes = Object.assign(bidRequests[0], mediaTypes);
      const requestWithBannerSizes = spec.buildRequests([bidRequestWithBannerSizes], bidderResquestDefault);
      const payloadWithBannerSizes = JSON.parse(requestWithBannerSizes.data);

      return payloadWithBannerSizes.data.forEach(bid => {
        if (Array.isArray(expectedSizes)) {
          expect(JSON.stringify(bid.sizes)).to.equal(JSON.stringify(expectedSizes));
        } else {
          expect(bid.sizes[0]).to.equal(expectedSizes);
        }
      });
    }
  });

  describe('interpretResponse', function() {
    it('should get correct bid responses', function() {
      let bids = {
        'body': {
          'responses': [{
            'ad': AD_SCRIPT,
            'cpm': 0.5,
            'currency': 'USD',
            'height': 250,
            'bidId': '3ede2a3fa0db94',
            'ttl': 360,
            'width': 300,
            'creativeId': 'er2ee',
            'placementId': 34
          }, {
            'ad': AD_SCRIPT,
            'cpm': 0.5,
            'currency': 'USD',
            'height': 200,
            'bidId': '4fef3b4gb1ec15',
            'ttl': 360,
            'width': 350,
            'creativeId': 'fs3ff',
            'placementId': 34,
            'dealId': 'ABC_123'
          }]
        }
      };
      let expectedResponse = [
        {
          'cpm': 0.5,
          'width': 300,
          'height': 250,
          'currency': 'USD',
          'netRevenue': true,
          'meta': {
            advertiserDomains: []
          },
          'ttl': 360,
          'ad': AD_SCRIPT,
          'requestId': '3ede2a3fa0db94',
          'creativeId': 'er2ee',
          'placementId': 34
        }, {
          'cpm': 0.5,
          'width': 350,
          'height': 200,
          'currency': 'USD',
          'netRevenue': true,
          'meta': {
            advertiserDomains: []
          },
          'ttl': 360,
          'ad': AD_SCRIPT,
          'requestId': '4fef3b4gb1ec15',
          'creativeId': 'fs3ff',
          'placementId': 34,
          'dealId': 'ABC_123'
        }
      ]
      ;

      let result = spec.interpretResponse(bids);
      expect(result).to.eql(expectedResponse);
    });

    it('handles nobid responses', function() {
      let bids = {
        'body': {
          'responses': []
        }
      };

      let result = spec.interpretResponse(bids);
      expect(result.length).to.equal(0);
    });
  });
});


text:
Shout!
======

**A simple chat or "shoutbox" based on WebSockets, pure Javascript, and Python.**

![Screenshot](/Screenshot.png "Screenshot showcasing some of the features")

Simple and lightweight
----------------------
No images; No CSS classes; no Javascript framework; no backend dependencies. Pure HTML, CSS3, Javascript and Python.
Requires a modern browser (particularly IE10+).

Beautiful and full-featured
---------------------------
It adapts to a fluid design, allows username selection (handling username collisions), provides rate limiting and spam control (users can ignore particular commenters), etc.

Versatile
---------
The frontend can be easily adapted to your preferred Javascript framework, including jQuery. The lack of CSS classes means there will be minimum interference with your existing stylesheets.

The backend is **a custom, multi-threaded, asynchronous (non-blocking) HTTP/WebSockets server** ([RFC-2616](https://tools.ietf.org/html/rfc2616)/[RFC-6455](https://tools.ietf.org/html/rfc6455)) written in pure Python. It's however very limited and untested, and should be ported to a real server for production use. It can also be adapted to your programming language of choice using the original code as a guide.

Educational
-----------
I've developed Shout! to learn about WebSockets and low-level networking in Python, and I've commented the code to guide you through my steps.

For your convenience the entire project is contained in only two files: a [.html](/shout.html) for the frontend and a [.py](shout.py) for the backend.

MIT-Licensed
------------
Feel free to use, edit, or distribute this code in any way you want. Check out the [GitHub repository](https://github.com/jsantirso/shout/); your contributions will be more than welcome.

Usage
=====
- Download shout.html and shout.py and place them in the same folder
- Execute shout.py
- Navigate to /localhost in your preferred browser(s)


text:
! dpp \
    && echo "test failed: dpp returned with non-zero exit code $?" && exit 1

dpp run ./tests/cli/raise-exception \
    && echo "test failed: exception in pipeline returned successful exit code" && exit 1

dpp run ./tests/cli/failure-no-errors \
    && echo "test failed: pipeline that failed without errors returned successful exit code" && exit 1

! dpp run ./tests/cli/success \
    && echo "test failed: success pipeline returned with non-zero exit code $?" && exit 1

dpp run --concurrency 4 \
        ./tests/cli/raise-exception,./tests/env/dummy/pipeline-test-data%,./tests/cli/failure-no-errors \
    && echo "test failed: concurrent run with failures returned successful exit code" && exit 1

! dpp run --concurrency 2 \
          ./tests/cli/success,./tests/cli/verbose-logs-with-sleep,./tests/env/dummy/pipeline-test-data% \
    && echo "test failed: concurrent run without failures returned non-zero exit code $?" && exit 1

echo "Great Success"
exit 0


text:
module SolidusKlarnaPayments
  class StoreCustomerTokenService < BaseService
    def initialize(order:, customer_token:)
      @user = order&.user
      @customer_token = customer_token

      super()
    end

    def call
      return false unless user

      user.update(klarna_customer_token: customer_token)
    end

    private

    attr_reader :user, :customer_token
  end
end