package resa.evaluation.scheduler; import backtype.storm.Config; import backtype.storm.scheduler.ExecutorDetails; import backtype.storm.utils.Utils; import org.apache.curator.framework.CuratorFramework; import org.junit.After; import org.junit.Before; import org.junit.Test; import resa.util.TopologyHelper; import java.util.*; import java.util.stream.Collectors; /** * Created by ding on 14-8-6. */ public class SchedulerTest { private CuratorFramework zk; private Map<String, Object> conf; @Before public void init() { conf = Utils.readStormConfig(); conf.put(Config.NIMBUS_HOST, "192.168.0.30"); conf.put(Config.STORM_ZOOKEEPER_SERVERS, Arrays.asList("192.168.0.30")); zk = Utils.newCuratorStarted(conf, (List<String>) conf.get(Config.STORM_ZOOKEEPER_SERVERS), conf.get(Config.STORM_ZOOKEEPER_PORT)); } @Test public void assignment2InitState() throws Exception { String topoId = TopologyHelper.getTopologyId("test", conf); Map<String, Map<ExecutorDetails, String>> assignment = TopologyHelper.getAssignment(conf, topoId); String[] workers = assignment.values().stream().flatMap(m -> m.values().stream()).distinct().sorted() .toArray(String[]::new); Map<ExecutorDetails, String> compAssignment = assignment.get("data-loader"); ExecutorDetails[] executors = compAssignment.keySet().stream() .sorted(Comparator.comparing(ExecutorDetails::getStartTask)).toArray(ExecutorDetails[]::new); int[] alloc = packAvg(executors.length, workers.length); Map<String, String> exe2WorkerSlot = new HashMap<>(); int j = 0; for (int i = 0; i < alloc.length; i++) { for (int k = 0; k < alloc[i]; k++) { exe2WorkerSlot.put(executors[j].getStartTask() + "-" + executors[j].getEndTask(), workers[i]); j++; } } System.out.println(exe2WorkerSlot); String path = "/resa/" + topoId; if (zk.checkExists().forPath(path) != null) { zk.setData().forPath(path, Utils.serialize(new HashMap<>(Collections.singletonMap("assignment", exe2WorkerSlot)))); } else { zk.create().creatingParentsIfNeeded().forPath(path, Utils.serialize( new HashMap<>(Collections.singletonMap("assignment", exe2WorkerSlot)))); } } @Test public void changeAssignment() throws Exception { String topoId = TopologyHelper.getTopologyId("test", conf); Map<String, Map<ExecutorDetails, String>> assignment = TopologyHelper.getAssignment(conf, topoId); List<String> workers = assignment.values().stream().flatMap(m -> m.values().stream()).distinct() .collect(Collectors.toList()); int numToMove = 9; Map<ExecutorDetails, String> compAssignment = assignment.get("data-loader"); Set<ExecutorDetails> toMove = new HashSet<>(); int[] moveCnt = packAvg(numToMove, workers.size()); for (int i = 0; i < moveCnt.length; i++) { String worker = workers.get(i); compAssignment.entrySet().stream().filter(e -> e.getValue().equals(worker)).limit(moveCnt[i]) .map(e -> e.getKey()).forEach(toMove::add); } toMove.forEach(e -> { Collections.shuffle(workers); compAssignment.compute(e, (exe, worker) -> workers.stream().filter(w -> !w.equals(worker)) .findAny().get()); }); setAssignment(topoId, compAssignment); } private void setAssignment(String tid, Map<ExecutorDetails, String> compAssignment) throws Exception { Map<String, String> exe2WorkerSlot = new HashMap<>(); String path = "/resa/" + tid; compAssignment.forEach((k, v) -> exe2WorkerSlot.put(k.getStartTask() + "-" + k.getEndTask(), v)); zk.setData().forPath(path, Utils.serialize(new HashMap<>(Collections.singletonMap("assignment", exe2WorkerSlot)))); } private static int[] packAvg(int eleCount, int packCount) { int[] ret = new int[packCount]; Arrays.fill(ret, eleCount / packCount); int k = eleCount % packCount; for (int i = 0; i < k; i++) { ret[i]++; } return ret; } @Test public void testModifyExecutors() throws Exception { String path = "/resa/wc-2-1407306985"; if (zk.checkExists().forPath(path) == null) { zk.create().forPath(path); } Map<String, Object> assignment = new HashMap<>(); Map<String, String> exe2Comp = new HashMap<>(); exe2Comp.put("5-6", "counter"); exe2Comp.put("7-10", "counter"); exe2Comp.put("11-14", "counter"); exe2Comp.put("15-16", "counter"); assignment.put("executors", exe2Comp); zk.setData().forPath(path, Utils.serialize(assignment)); } @Test public void testModifyAssignment() throws Exception { String path = "/resa/wc-2-1407306985"; if (zk.checkExists().forPath(path) == null) { zk.create().forPath(path); } Map<String, Object> assignment = new HashMap<>(); Map<String, String> exe2Comp = new HashMap<>(); exe2Comp.put("5-6", "counter"); exe2Comp.put("7-10", "counter"); exe2Comp.put("11-14", "counter"); exe2Comp.put("15-16", "counter"); assignment.put("executors", exe2Comp); Map<String, String> exe2WorkerSlot = new HashMap<>(); exe2WorkerSlot.put("7-10", "yy08-Precision-T1650:6702"); exe2WorkerSlot.put("5-6", "yy07-Precision-T1650:6701"); assignment.put("assignment", exe2WorkerSlot); zk.setData().forPath(path, Utils.serialize(assignment)); } @After public void cleanup() { zk.close(); } }