blob: 70b5cb0f9395c7315d7838010a2a16209fce1d81 [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed 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.
*/
package org.onlab.stc;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.onlab.stc.Coordinator.Status;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.stc.Coordinator.Status.*;
import static org.onlab.stc.Coordinator.print;
/**
* Maintains state of scenario execution.
*/
class ScenarioStore {
private final ProcessFlow processFlow;
private final File storeFile;
private final File logDir;
private final List<StepEvent> events = Lists.newArrayList();
private final Map<String, Status> statusMap = Maps.newConcurrentMap();
/**
* Creates a new scenario store for the specified process flow.
*
* @param processFlow scenario process flow
* @param logDir scenario log directory
* @param name scenario name
*/
ScenarioStore(ProcessFlow processFlow, File logDir, String name) {
this.processFlow = processFlow;
this.logDir = logDir;
this.storeFile = new File(logDir, name + ".stc");
load();
}
/**
* Resets status of all steps to waiting and clears all events.
*/
void reset() {
events.clear();
statusMap.clear();
processFlow.getVertexes().forEach(step -> statusMap.put(step.name(), WAITING));
try {
removeLogs();
PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
cfg.clear();
cfg.save();
} catch (ConfigurationException e) {
print("Unable to store file %s", storeFile);
}
}
/**
* Returns set of all test steps.
*
* @return set of steps
*/
Set<Step> getSteps() {
return processFlow.getVertexes();
}
/**
* Returns a chronological list of step or group records.
*
* @return list of events
*/
synchronized List<StepEvent> getEvents() {
return ImmutableList.copyOf(events);
}
/**
* Returns the status record of the specified test step.
*
* @param step test step or group
* @return step status record
*/
Status getStatus(Step step) {
return checkNotNull(statusMap.get(step.name()), "Step %s not found", step.name());
}
/**
* Marks the specified test step as being in progress.
*
* @param step test step or group
*/
synchronized void markStarted(Step step) {
add(new StepEvent(step.name(), IN_PROGRESS));
save();
}
/**
* Marks the specified test step as being complete.
*
* @param step test step or group
* @param status new step status
*/
synchronized void markComplete(Step step, Status status) {
add(new StepEvent(step.name(), status));
save();
}
/**
* Indicates whether there are any failures.
*
* @return true if there are failed steps
*/
boolean hasFailures() {
for (Status status : statusMap.values()) {
if (status == FAILED) {
return true;
}
}
return false;
}
/**
* Registers a new step record.
*
* @param event step event
*/
private synchronized void add(StepEvent event) {
events.add(event);
statusMap.put(event.name(), event.status());
}
/**
* Loads the states from disk.
*/
private void load() {
try {
PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
cfg.getKeys().forEachRemaining(prop -> add(StepEvent.fromString(cfg.getString(prop))));
cfg.save();
} catch (ConfigurationException e) {
print("Unable to store file %s", storeFile);
}
}
/**
* Saves the states to disk.
*/
private void save() {
try {
PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
events.forEach(event -> cfg.setProperty("T" + event.time(), event.toString()));
cfg.save();
} catch (ConfigurationException e) {
print("Unable to store file %s", storeFile);
}
}
/**
* Removes all scenario log files.
*/
private void removeLogs() {
File[] logFiles = logDir.listFiles();
if (logFiles != null && logFiles.length > 0) {
for (File file : logFiles) {
if (!file.delete()) {
print("Unable to delete log file %s", file);
}
}
}
}
}