Committed by
Gerrit Code Review
ONOS-1315 Adding configurability to intent performance test app.
Change-Id: I2782bdc0f78cc49aa60af1fa03eae91a2fd6bce0
Showing
7 changed files
with
240 additions
and
61 deletions
| ... | @@ -42,6 +42,10 @@ | ... | @@ -42,6 +42,10 @@ |
| 42 | <artifactId>onos-cli</artifactId> | 42 | <artifactId>onos-cli</artifactId> |
| 43 | <version>${project.version}</version> | 43 | <version>${project.version}</version> |
| 44 | </dependency> | 44 | </dependency> |
| 45 | + <dependency> | ||
| 46 | + <groupId>org.osgi</groupId> | ||
| 47 | + <artifactId>org.osgi.compendium</artifactId> | ||
| 48 | + </dependency> | ||
| 45 | </dependencies> | 49 | </dependencies> |
| 46 | 50 | ||
| 47 | <build> | 51 | <build> | ... | ... |
| ... | @@ -50,7 +50,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -50,7 +50,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 50 | @Service(value = IntentPerfCollector.class) | 50 | @Service(value = IntentPerfCollector.class) |
| 51 | public class IntentPerfCollector { | 51 | public class IntentPerfCollector { |
| 52 | 52 | ||
| 53 | - private static final long SAMPLE_WINDOW = 5_000; | 53 | + private static final long SAMPLE_TIME_WINDOW_MS = 5_000; |
| 54 | private final Logger log = getLogger(getClass()); | 54 | private final Logger log = getLogger(getClass()); |
| 55 | 55 | ||
| 56 | private static final int MAX_SAMPLES = 1_000; | 56 | private static final int MAX_SAMPLES = 1_000; |
| ... | @@ -82,9 +82,9 @@ public class IntentPerfCollector { | ... | @@ -82,9 +82,9 @@ public class IntentPerfCollector { |
| 82 | 82 | ||
| 83 | @Activate | 83 | @Activate |
| 84 | public void activate() { | 84 | public void activate() { |
| 85 | - this.nodeId = clusterService.getLocalNode().id(); | 85 | + nodeId = clusterService.getLocalNode().id(); |
| 86 | - this.newestTime = 0; | ||
| 87 | 86 | ||
| 87 | + // TODO: replace with shared executor | ||
| 88 | messageHandlingExecutor = Executors.newSingleThreadExecutor( | 88 | messageHandlingExecutor = Executors.newSingleThreadExecutor( |
| 89 | groupedThreads("onos/perf", "message-handler")); | 89 | groupedThreads("onos/perf", "message-handler")); |
| 90 | 90 | ||
| ... | @@ -98,9 +98,8 @@ public class IntentPerfCollector { | ... | @@ -98,9 +98,8 @@ public class IntentPerfCollector { |
| 98 | for (int i = 0; i < nodes.length; i++) { | 98 | for (int i = 0; i < nodes.length; i++) { |
| 99 | nodeToIndex.put(nodes[i].id(), i); | 99 | nodeToIndex.put(nodes[i].id(), i); |
| 100 | } | 100 | } |
| 101 | - overall = new Sample(0, nodes.length); | ||
| 102 | - current = new Sample(0, nodes.length); | ||
| 103 | 101 | ||
| 102 | + clearSamples(); | ||
| 104 | log.info("Started"); | 103 | log.info("Started"); |
| 105 | } | 104 | } |
| 106 | 105 | ||
| ... | @@ -112,19 +111,26 @@ public class IntentPerfCollector { | ... | @@ -112,19 +111,26 @@ public class IntentPerfCollector { |
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | /** | 113 | /** |
| 114 | + * Clears all previously accumulated data. | ||
| 115 | + */ | ||
| 116 | + public void clearSamples() { | ||
| 117 | + newestTime = 0; | ||
| 118 | + overall = new Sample(0, nodes.length); | ||
| 119 | + current = new Sample(0, nodes.length); | ||
| 120 | + samples.clear(); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + | ||
| 124 | + /** | ||
| 115 | * Records a sample point of data about intent operation rate. | 125 | * Records a sample point of data about intent operation rate. |
| 116 | * | 126 | * |
| 117 | * @param overallRate overall rate | 127 | * @param overallRate overall rate |
| 118 | * @param currentRate current rate | 128 | * @param currentRate current rate |
| 119 | */ | 129 | */ |
| 120 | public void recordSample(double overallRate, double currentRate) { | 130 | public void recordSample(double overallRate, double currentRate) { |
| 121 | - try { | 131 | + long now = System.currentTimeMillis(); |
| 122 | - long now = System.currentTimeMillis(); | 132 | + addSample(now, nodeId, overallRate, currentRate); |
| 123 | - addSample(now, nodeId, overallRate, currentRate); | 133 | + broadcastSample(now, nodeId, overallRate, currentRate); |
| 124 | - broadcastSample(now, nodeId, overallRate, currentRate); | ||
| 125 | - } catch (Exception e) { | ||
| 126 | - log.error("Boom!", e); | ||
| 127 | - } | ||
| 128 | } | 134 | } |
| 129 | 135 | ||
| 130 | /** | 136 | /** |
| ... | @@ -173,7 +179,7 @@ public class IntentPerfCollector { | ... | @@ -173,7 +179,7 @@ public class IntentPerfCollector { |
| 173 | } | 179 | } |
| 174 | 180 | ||
| 175 | private Sample createCurrentSampleIfNeeded(long time) { | 181 | private Sample createCurrentSampleIfNeeded(long time) { |
| 176 | - Sample oldSample = time - newestTime > SAMPLE_WINDOW || current.isComplete() ? current : null; | 182 | + Sample oldSample = time - newestTime > SAMPLE_TIME_WINDOW_MS || current.isComplete() ? current : null; |
| 177 | if (oldSample != null) { | 183 | if (oldSample != null) { |
| 178 | newestTime = time; | 184 | newestTime = time; |
| 179 | current = new Sample(time, nodes.length); | 185 | current = new Sample(time, nodes.length); |
| ... | @@ -227,9 +233,9 @@ public class IntentPerfCollector { | ... | @@ -227,9 +233,9 @@ public class IntentPerfCollector { |
| 227 | @Override | 233 | @Override |
| 228 | public void handle(ClusterMessage message) { | 234 | public void handle(ClusterMessage message) { |
| 229 | String[] fields = new String(message.payload()).split("\\|"); | 235 | String[] fields = new String(message.payload()).split("\\|"); |
| 230 | - log.info("Received sample from {}: {}", message.sender(), fields); | 236 | + log.debug("Received sample from {}: {}", message.sender(), fields); |
| 231 | addSample(Long.parseLong(fields[0]), message.sender(), | 237 | addSample(Long.parseLong(fields[0]), message.sender(), |
| 232 | - Double.parseDouble(fields[1]), Double.parseDouble(fields[1])); | 238 | + Double.parseDouble(fields[1]), Double.parseDouble(fields[2])); |
| 233 | } | 239 | } |
| 234 | } | 240 | } |
| 235 | } | 241 | } | ... | ... |
| ... | @@ -24,8 +24,11 @@ import org.apache.commons.lang.math.RandomUtils; | ... | @@ -24,8 +24,11 @@ import org.apache.commons.lang.math.RandomUtils; |
| 24 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
| 25 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
| 26 | import org.apache.felix.scr.annotations.Deactivate; | 26 | import org.apache.felix.scr.annotations.Deactivate; |
| 27 | +import org.apache.felix.scr.annotations.Modified; | ||
| 27 | import org.apache.felix.scr.annotations.Property; | 28 | import org.apache.felix.scr.annotations.Property; |
| 28 | import org.apache.felix.scr.annotations.Reference; | 29 | import org.apache.felix.scr.annotations.Reference; |
| 30 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 31 | +import org.apache.felix.scr.annotations.Service; | ||
| 29 | import org.onlab.packet.MacAddress; | 32 | import org.onlab.packet.MacAddress; |
| 30 | import org.onlab.util.Counter; | 33 | import org.onlab.util.Counter; |
| 31 | import org.onosproject.cfg.ComponentConfigService; | 34 | import org.onosproject.cfg.ComponentConfigService; |
| ... | @@ -50,10 +53,16 @@ import org.onosproject.net.intent.IntentService; | ... | @@ -50,10 +53,16 @@ import org.onosproject.net.intent.IntentService; |
| 50 | import org.onosproject.net.intent.Key; | 53 | import org.onosproject.net.intent.Key; |
| 51 | import org.onosproject.net.intent.PartitionService; | 54 | import org.onosproject.net.intent.PartitionService; |
| 52 | import org.onosproject.net.intent.PointToPointIntent; | 55 | import org.onosproject.net.intent.PointToPointIntent; |
| 56 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
| 57 | +import org.onosproject.store.cluster.messaging.ClusterMessage; | ||
| 58 | +import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | ||
| 59 | +import org.onosproject.store.cluster.messaging.MessageSubject; | ||
| 60 | +import org.osgi.service.component.ComponentContext; | ||
| 53 | import org.slf4j.Logger; | 61 | import org.slf4j.Logger; |
| 54 | 62 | ||
| 55 | import java.util.ArrayList; | 63 | import java.util.ArrayList; |
| 56 | import java.util.Collections; | 64 | import java.util.Collections; |
| 65 | +import java.util.Dictionary; | ||
| 57 | import java.util.List; | 66 | import java.util.List; |
| 58 | import java.util.Map; | 67 | import java.util.Map; |
| 59 | import java.util.Set; | 68 | import java.util.Set; |
| ... | @@ -65,11 +74,11 @@ import java.util.concurrent.TimeUnit; | ... | @@ -65,11 +74,11 @@ import java.util.concurrent.TimeUnit; |
| 65 | import java.util.stream.Collectors; | 74 | import java.util.stream.Collectors; |
| 66 | 75 | ||
| 67 | import static com.google.common.base.Preconditions.checkState; | 76 | import static com.google.common.base.Preconditions.checkState; |
| 77 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
| 68 | import static java.lang.String.format; | 78 | import static java.lang.String.format; |
| 69 | import static java.lang.System.currentTimeMillis; | 79 | import static java.lang.System.currentTimeMillis; |
| 70 | import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; | 80 | import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; |
| 71 | -import static org.onlab.util.Tools.delay; | 81 | +import static org.onlab.util.Tools.*; |
| 72 | -import static org.onlab.util.Tools.groupedThreads; | ||
| 73 | import static org.onosproject.net.intent.IntentEvent.Type.*; | 82 | import static org.onosproject.net.intent.IntentEvent.Type.*; |
| 74 | import static org.slf4j.LoggerFactory.getLogger; | 83 | import static org.slf4j.LoggerFactory.getLogger; |
| 75 | 84 | ||
| ... | @@ -77,20 +86,25 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -77,20 +86,25 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 77 | * Application to test sustained intent throughput. | 86 | * Application to test sustained intent throughput. |
| 78 | */ | 87 | */ |
| 79 | @Component(immediate = true) | 88 | @Component(immediate = true) |
| 89 | +@Service(value = IntentPerfInstaller.class) | ||
| 80 | public class IntentPerfInstaller { | 90 | public class IntentPerfInstaller { |
| 81 | 91 | ||
| 82 | private final Logger log = getLogger(getClass()); | 92 | private final Logger log = getLogger(getClass()); |
| 83 | 93 | ||
| 84 | private static final int DEFAULT_NUM_WORKERS = 1; | 94 | private static final int DEFAULT_NUM_WORKERS = 1; |
| 85 | 95 | ||
| 86 | - private static final int DEFAULT_NUM_KEYS = 40_000; | 96 | + private static final int DEFAULT_NUM_KEYS = 40000; |
| 87 | - private static final int DEFAULT_GOAL_CYCLE_PERIOD = 1_000; //ms | 97 | + private static final int DEFAULT_GOAL_CYCLE_PERIOD = 1000; //ms |
| 88 | 98 | ||
| 89 | private static final int DEFAULT_NUM_NEIGHBORS = 0; | 99 | private static final int DEFAULT_NUM_NEIGHBORS = 0; |
| 90 | 100 | ||
| 91 | private static final int START_DELAY = 5_000; // ms | 101 | private static final int START_DELAY = 5_000; // ms |
| 92 | private static final int REPORT_PERIOD = 5_000; //ms | 102 | private static final int REPORT_PERIOD = 5_000; //ms |
| 93 | 103 | ||
| 104 | + private static final String START = "start"; | ||
| 105 | + private static final String STOP = "stop"; | ||
| 106 | + private static final MessageSubject CONTROL = new MessageSubject("intent-perf-ctl"); | ||
| 107 | + | ||
| 94 | //FIXME add path length | 108 | //FIXME add path length |
| 95 | 109 | ||
| 96 | @Property(name = "numKeys", intValue = DEFAULT_NUM_KEYS, | 110 | @Property(name = "numKeys", intValue = DEFAULT_NUM_KEYS, |
| ... | @@ -134,6 +148,11 @@ public class IntentPerfInstaller { | ... | @@ -134,6 +148,11 @@ public class IntentPerfInstaller { |
| 134 | @Reference(cardinality = MANDATORY_UNARY) | 148 | @Reference(cardinality = MANDATORY_UNARY) |
| 135 | protected IntentPerfCollector sampleCollector; | 149 | protected IntentPerfCollector sampleCollector; |
| 136 | 150 | ||
| 151 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 152 | + protected ClusterCommunicationService communicationService; | ||
| 153 | + | ||
| 154 | + private ExecutorService messageHandlingExecutor; | ||
| 155 | + | ||
| 137 | private ExecutorService workers; | 156 | private ExecutorService workers; |
| 138 | private ApplicationId appId; | 157 | private ApplicationId appId; |
| 139 | private Listener listener; | 158 | private Listener listener; |
| ... | @@ -145,86 +164,138 @@ public class IntentPerfInstaller { | ... | @@ -145,86 +164,138 @@ public class IntentPerfInstaller { |
| 145 | private int lastKey = 0; | 164 | private int lastKey = 0; |
| 146 | 165 | ||
| 147 | private IntentPerfUi perfUi; | 166 | private IntentPerfUi perfUi; |
| 167 | + private NodeId nodeId; | ||
| 168 | + private TimerTask reporterTask; | ||
| 148 | 169 | ||
| 149 | @Activate | 170 | @Activate |
| 150 | - public void activate() { | 171 | + public void activate(ComponentContext context) { |
| 151 | -// configService.registerProperties(getClass()); | 172 | + configService.registerProperties(getClass()); |
| 152 | 173 | ||
| 153 | - String nodeId = clusterService.getLocalNode().ip().toString(); | 174 | + nodeId = clusterService.getLocalNode().id(); |
| 154 | - appId = coreService.registerApplication("org.onosproject.intentperf." + nodeId); | 175 | + appId = coreService.registerApplication("org.onosproject.intentperf." + nodeId.toString()); |
| 155 | 176 | ||
| 177 | + // TODO: replace with shared timer | ||
| 156 | reportTimer = new Timer("onos-intent-perf-reporter"); | 178 | reportTimer = new Timer("onos-intent-perf-reporter"); |
| 157 | workers = Executors.newFixedThreadPool(DEFAULT_NUM_WORKERS, groupedThreads("onos/intent-perf", "worker-%d")); | 179 | workers = Executors.newFixedThreadPool(DEFAULT_NUM_WORKERS, groupedThreads("onos/intent-perf", "worker-%d")); |
| 158 | 180 | ||
| 159 | - | ||
| 160 | // disable flow backups for testing | 181 | // disable flow backups for testing |
| 161 | log.info("flow props: {}", | 182 | log.info("flow props: {}", |
| 162 | configService.getProperties("org.onosproject.store.flow.impl.DistributedFlowRuleStore")); | 183 | configService.getProperties("org.onosproject.store.flow.impl.DistributedFlowRuleStore")); |
| 163 | configService.setProperty("org.onosproject.store.flow.impl.DistributedFlowRuleStore", | 184 | configService.setProperty("org.onosproject.store.flow.impl.DistributedFlowRuleStore", |
| 164 | "backupEnabled", "false"); | 185 | "backupEnabled", "false"); |
| 165 | 186 | ||
| 166 | - // Schedule delayed start | 187 | + // TODO: replace with shared executor |
| 167 | - reportTimer.schedule(new TimerTask() { | 188 | + messageHandlingExecutor = Executors.newSingleThreadExecutor( |
| 168 | - @Override | 189 | + groupedThreads("onos/perf", "command-handler")); |
| 169 | - public void run() { | 190 | + |
| 170 | - start(); | 191 | + communicationService.addSubscriber(CONTROL, new InternalControl(), |
| 171 | - } | 192 | + messageHandlingExecutor); |
| 172 | - }, START_DELAY); | 193 | + |
| 194 | + listener = new Listener(); | ||
| 195 | + intentService.addListener(listener); | ||
| 196 | + | ||
| 197 | + // TODO: investigate why this seems to be necessary for configs to get picked up on initial activation | ||
| 198 | + modify(context); | ||
| 173 | } | 199 | } |
| 174 | 200 | ||
| 175 | @Deactivate | 201 | @Deactivate |
| 176 | public void deactivate() { | 202 | public void deactivate() { |
| 177 | -// configService.unregisterProperties(getClass(), false); | 203 | + stopTestRun(); |
| 178 | - stop(); | 204 | + |
| 205 | + configService.unregisterProperties(getClass(), false); | ||
| 206 | + messageHandlingExecutor.shutdown(); | ||
| 207 | + communicationService.removeSubscriber(CONTROL); | ||
| 208 | + | ||
| 209 | + if (listener != null) { | ||
| 210 | + reportTimer.cancel(); | ||
| 211 | + intentService.removeListener(listener); | ||
| 212 | + listener = null; | ||
| 213 | + reportTimer = null; | ||
| 214 | + } | ||
| 179 | } | 215 | } |
| 180 | 216 | ||
| 181 | - //FIXME add modified | 217 | + @Modified |
| 218 | + public void modify(ComponentContext context) { | ||
| 219 | + if (context == null) { | ||
| 220 | + logConfig("Reconfigured"); | ||
| 221 | + return; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + Dictionary<?, ?> properties = context.getProperties(); | ||
| 225 | + int newNumKeys, newCyclePeriod, newNumNeighbors; | ||
| 226 | + try { | ||
| 227 | + String s = get(properties, "numKeys"); | ||
| 228 | + newNumKeys = isNullOrEmpty(s) ? numKeys : Integer.parseInt(s.trim()); | ||
| 229 | + | ||
| 230 | + s = get(properties, "cyclePeriod"); | ||
| 231 | + newCyclePeriod = isNullOrEmpty(s) ? cyclePeriod : Integer.parseInt(s.trim()); | ||
| 232 | + | ||
| 233 | + s = get(properties, "numNeighbors"); | ||
| 234 | + newNumNeighbors = isNullOrEmpty(s) ? numNeighbors : Integer.parseInt(s.trim()); | ||
| 235 | + | ||
| 236 | + } catch (NumberFormatException | ClassCastException e) { | ||
| 237 | + log.warn("Malformed configuration detected; using defaults", e); | ||
| 238 | + newNumKeys = DEFAULT_NUM_KEYS; | ||
| 239 | + newCyclePeriod = DEFAULT_GOAL_CYCLE_PERIOD; | ||
| 240 | + newNumNeighbors = DEFAULT_NUM_NEIGHBORS; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + if (newNumKeys != numKeys || newCyclePeriod != cyclePeriod || newNumNeighbors != numNeighbors) { | ||
| 244 | + numKeys = newNumKeys; | ||
| 245 | + cyclePeriod = newCyclePeriod; | ||
| 246 | + numNeighbors = newNumNeighbors; | ||
| 247 | + logConfig("Reconfigured"); | ||
| 248 | + } | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + public void start() { | ||
| 252 | + communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, START.getBytes())); | ||
| 253 | + startTestRun(); | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + public void stop() { | ||
| 257 | + communicationService.broadcast(new ClusterMessage(nodeId, CONTROL, STOP.getBytes())); | ||
| 258 | + stopTestRun(); | ||
| 259 | + } | ||
| 182 | 260 | ||
| 183 | private void logConfig(String prefix) { | 261 | private void logConfig(String prefix) { |
| 184 | log.info("{} with appId {}; numKeys = {}; cyclePeriod = {} ms; numNeighbors={}", | 262 | log.info("{} with appId {}; numKeys = {}; cyclePeriod = {} ms; numNeighbors={}", |
| 185 | prefix, appId.id(), numKeys, cyclePeriod, numNeighbors); | 263 | prefix, appId.id(), numKeys, cyclePeriod, numNeighbors); |
| 186 | } | 264 | } |
| 187 | 265 | ||
| 188 | - public void start() { | 266 | + private void startTestRun() { |
| 267 | + sampleCollector.clearSamples(); | ||
| 268 | + | ||
| 189 | // adjust numNeighbors and generate list of neighbors | 269 | // adjust numNeighbors and generate list of neighbors |
| 190 | numNeighbors = Math.min(clusterService.getNodes().size() - 1, numNeighbors); | 270 | numNeighbors = Math.min(clusterService.getNodes().size() - 1, numNeighbors); |
| 191 | 271 | ||
| 192 | - // perhaps we want to prime before listening... | ||
| 193 | - // we will need to discard the first few results for priming and warmup | ||
| 194 | - listener = new Listener(); | ||
| 195 | - intentService.addListener(listener); | ||
| 196 | - | ||
| 197 | // Schedule reporter task on report period boundary | 272 | // Schedule reporter task on report period boundary |
| 198 | - reportTimer.scheduleAtFixedRate(new TimerTask() { | 273 | + reporterTask = new ReporterTask(); |
| 199 | - @Override | 274 | + reportTimer.scheduleAtFixedRate(reporterTask, |
| 200 | - public void run() { | 275 | + REPORT_PERIOD - currentTimeMillis() % REPORT_PERIOD, |
| 201 | - //adjustRates(); // FIXME we currently adjust rates in the cycle thread | 276 | + REPORT_PERIOD); |
| 202 | - listener.report(); | ||
| 203 | - } | ||
| 204 | - }, REPORT_PERIOD - currentTimeMillis() % REPORT_PERIOD, REPORT_PERIOD); | ||
| 205 | 277 | ||
| 206 | // Submit workers | 278 | // Submit workers |
| 207 | stopped = false; | 279 | stopped = false; |
| 208 | for (int i = 0; i < DEFAULT_NUM_WORKERS; i++) { | 280 | for (int i = 0; i < DEFAULT_NUM_WORKERS; i++) { |
| 209 | workers.submit(new Submitter(createIntents(numKeys, /*FIXME*/ 2, lastKey))); | 281 | workers.submit(new Submitter(createIntents(numKeys, /*FIXME*/ 2, lastKey))); |
| 210 | } | 282 | } |
| 211 | - logConfig("Started"); | 283 | + log.info("Started test run"); |
| 212 | } | 284 | } |
| 213 | 285 | ||
| 214 | - public void stop() { | 286 | + private void stopTestRun() { |
| 215 | stopped = true; | 287 | stopped = true; |
| 216 | - if (listener != null) { | 288 | + if (reporterTask != null) { |
| 217 | - reportTimer.cancel(); | 289 | + reporterTask.cancel(); |
| 218 | - intentService.removeListener(listener); | 290 | + reporterTask = null; |
| 219 | - listener = null; | ||
| 220 | - reportTimer = null; | ||
| 221 | } | 291 | } |
| 292 | + | ||
| 222 | try { | 293 | try { |
| 223 | - workers.awaitTermination(5, TimeUnit.SECONDS); | 294 | + workers.awaitTermination(5 * cyclePeriod, TimeUnit.MILLISECONDS); |
| 224 | } catch (InterruptedException e) { | 295 | } catch (InterruptedException e) { |
| 225 | log.warn("Failed to stop worker", e); | 296 | log.warn("Failed to stop worker", e); |
| 226 | } | 297 | } |
| 227 | - log.info("Stopped"); | 298 | + log.info("Stopped test run"); |
| 228 | } | 299 | } |
| 229 | 300 | ||
| 230 | private List<NodeId> getNeighbors() { | 301 | private List<NodeId> getNeighbors() { |
| ... | @@ -491,4 +562,25 @@ public class IntentPerfInstaller { | ... | @@ -491,4 +562,25 @@ public class IntentPerfInstaller { |
| 491 | } | 562 | } |
| 492 | } | 563 | } |
| 493 | 564 | ||
| 565 | + private class InternalControl implements ClusterMessageHandler { | ||
| 566 | + @Override | ||
| 567 | + public void handle(ClusterMessage message) { | ||
| 568 | + String cmd = new String(message.payload()); | ||
| 569 | + log.info("Received command {}", cmd); | ||
| 570 | + if (cmd.equals(START)) { | ||
| 571 | + startTestRun(); | ||
| 572 | + } else { | ||
| 573 | + stopTestRun(); | ||
| 574 | + } | ||
| 575 | + } | ||
| 576 | + } | ||
| 577 | + | ||
| 578 | + private class ReporterTask extends TimerTask { | ||
| 579 | + @Override | ||
| 580 | + public void run() { | ||
| 581 | + //adjustRates(); // FIXME we currently adjust rates in the cycle thread | ||
| 582 | + listener.report(); | ||
| 583 | + } | ||
| 584 | + } | ||
| 585 | + | ||
| 494 | } | 586 | } | ... | ... |
| ... | @@ -29,7 +29,7 @@ import java.util.List; | ... | @@ -29,7 +29,7 @@ import java.util.List; |
| 29 | */ | 29 | */ |
| 30 | @Command(scope = "onos", name = "intent-perf", | 30 | @Command(scope = "onos", name = "intent-perf", |
| 31 | description = "Displays accumulated performance metrics") | 31 | description = "Displays accumulated performance metrics") |
| 32 | -public class IntentPerfCommand extends AbstractShellCommand { | 32 | +public class IntentPerfListCommand extends AbstractShellCommand { |
| 33 | 33 | ||
| 34 | @Option(name = "-s", aliases = "--summary", description = "Output just summary", | 34 | @Option(name = "-s", aliases = "--summary", description = "Output just summary", |
| 35 | required = false, multiValued = false) | 35 | required = false, multiValued = false) |
| ... | @@ -49,11 +49,16 @@ public class IntentPerfCommand extends AbstractShellCommand { | ... | @@ -49,11 +49,16 @@ public class IntentPerfCommand extends AbstractShellCommand { |
| 49 | List<String> headers = collector.getSampleHeaders(); | 49 | List<String> headers = collector.getSampleHeaders(); |
| 50 | Sample overall = collector.getOverall(); | 50 | Sample overall = collector.getOverall(); |
| 51 | double total = 0; | 51 | double total = 0; |
| 52 | + print("%12s: %14s", "Node ID", "Overall Rate"); | ||
| 52 | for (int i = 0; i < overall.data.length; i++) { | 53 | for (int i = 0; i < overall.data.length; i++) { |
| 53 | - print("%12s: %12.2f", headers.get(i), overall.data[i]); | 54 | + if (overall.data[i] >= 0) { |
| 54 | - total += overall.data[i]; | 55 | + print("%12s: %14.2f", headers.get(i), overall.data[i]); |
| 56 | + total += overall.data[i]; | ||
| 57 | + } else { | ||
| 58 | + print("%12s: %14s", headers.get(i), " "); | ||
| 59 | + } | ||
| 55 | } | 60 | } |
| 56 | - print("%12s: %12.2f", "total", total); | 61 | + print("%12s: %14.2f", "total", total); |
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | private void printSamples() { | 64 | private void printSamples() { | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.intentperf; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Command; | ||
| 19 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Starts intent performance test run. | ||
| 23 | + */ | ||
| 24 | +@Command(scope = "onos", name = "intent-perf-start", | ||
| 25 | + description = "Starts intent performance test run") | ||
| 26 | +public class IntentPerfStartCommand extends AbstractShellCommand { | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + protected void execute() { | ||
| 30 | + get(IntentPerfInstaller.class).start(); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.intentperf; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Command; | ||
| 19 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Stops intent performance test run. | ||
| 23 | + */ | ||
| 24 | +@Command(scope = "onos", name = "intent-perf-stop", | ||
| 25 | + description = "Stops intent performance test run") | ||
| 26 | +public class IntentPerfStopCommand extends AbstractShellCommand { | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + protected void execute() { | ||
| 30 | + get(IntentPerfInstaller.class).stop(); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | +} |
| ... | @@ -16,7 +16,13 @@ | ... | @@ -16,7 +16,13 @@ |
| 16 | <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | 16 | <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> |
| 17 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | 17 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> |
| 18 | <command> | 18 | <command> |
| 19 | - <action class="org.onosproject.intentperf.IntentPerfCommand"/> | 19 | + <action class="org.onosproject.intentperf.IntentPerfListCommand"/> |
| 20 | + </command> | ||
| 21 | + <command> | ||
| 22 | + <action class="org.onosproject.intentperf.IntentPerfStartCommand"/> | ||
| 23 | + </command> | ||
| 24 | + <command> | ||
| 25 | + <action class="org.onosproject.intentperf.IntentPerfStopCommand"/> | ||
| 20 | </command> | 26 | </command> |
| 21 | </command-bundle> | 27 | </command-bundle> |
| 22 | </blueprint> | 28 | </blueprint> | ... | ... |
-
Please register or login to post a comment