blob: 70b5cb0f9395c7315d7838010a2a16209fce1d81 [file] [log] [blame]
Thomas Vachuskaf9c84362015-04-15 11:20:45 -07001/*
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 */
16package org.onlab.stc;
17
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070020import com.google.common.collect.Maps;
21import org.apache.commons.configuration.ConfigurationException;
22import org.apache.commons.configuration.PropertiesConfiguration;
23import org.onlab.stc.Coordinator.Status;
24
25import java.io.File;
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070026import java.util.List;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070027import java.util.Map;
28import java.util.Set;
29
30import static com.google.common.base.Preconditions.checkNotNull;
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070031import static org.onlab.stc.Coordinator.Status.*;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070032import static org.onlab.stc.Coordinator.print;
33
34/**
35 * Maintains state of scenario execution.
36 */
37class ScenarioStore {
38
39 private final ProcessFlow processFlow;
40 private final File storeFile;
Thomas Vachuskaa48e3d12015-06-02 09:43:29 -070041 private final File logDir;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070042
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070043 private final List<StepEvent> events = Lists.newArrayList();
44 private final Map<String, Status> statusMap = Maps.newConcurrentMap();
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070045
46 /**
47 * Creates a new scenario store for the specified process flow.
48 *
49 * @param processFlow scenario process flow
50 * @param logDir scenario log directory
51 * @param name scenario name
52 */
53 ScenarioStore(ProcessFlow processFlow, File logDir, String name) {
54 this.processFlow = processFlow;
Thomas Vachuskaa48e3d12015-06-02 09:43:29 -070055 this.logDir = logDir;
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070056 this.storeFile = new File(logDir, name + ".stc");
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070057 load();
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070058 }
59
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070060 /**
61 * Resets status of all steps to waiting and clears all events.
62 */
63 void reset() {
64 events.clear();
65 statusMap.clear();
66 processFlow.getVertexes().forEach(step -> statusMap.put(step.name(), WAITING));
67 try {
Thomas Vachuskaa48e3d12015-06-02 09:43:29 -070068 removeLogs();
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070069 PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
70 cfg.clear();
71 cfg.save();
72 } catch (ConfigurationException e) {
73 print("Unable to store file %s", storeFile);
74 }
75
76 }
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070077
78 /**
79 * Returns set of all test steps.
80 *
81 * @return set of steps
82 */
83 Set<Step> getSteps() {
84 return processFlow.getVertexes();
85 }
86
87 /**
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070088 * Returns a chronological list of step or group records.
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070089 *
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070090 * @return list of events
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070091 */
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070092 synchronized List<StepEvent> getEvents() {
93 return ImmutableList.copyOf(events);
Thomas Vachuskaf9c84362015-04-15 11:20:45 -070094 }
95
96 /**
Thomas Vachuska50ec1af2015-06-02 00:42:52 -070097 * Returns the status record of the specified test step.
98 *
99 * @param step test step or group
100 * @return step status record
101 */
102 Status getStatus(Step step) {
103 return checkNotNull(statusMap.get(step.name()), "Step %s not found", step.name());
104 }
105
106 /**
107 * Marks the specified test step as being in progress.
108 *
109 * @param step test step or group
110 */
111 synchronized void markStarted(Step step) {
112 add(new StepEvent(step.name(), IN_PROGRESS));
113 save();
114 }
115
116 /**
117 * Marks the specified test step as being complete.
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700118 *
119 * @param step test step or group
120 * @param status new step status
121 */
Thomas Vachuska50ec1af2015-06-02 00:42:52 -0700122 synchronized void markComplete(Step step, Status status) {
123 add(new StepEvent(step.name(), status));
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700124 save();
125 }
126
127 /**
128 * Indicates whether there are any failures.
129 *
130 * @return true if there are failed steps
131 */
132 boolean hasFailures() {
Thomas Vachuska50ec1af2015-06-02 00:42:52 -0700133 for (Status status : statusMap.values()) {
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700134 if (status == FAILED) {
135 return true;
136 }
137 }
138 return false;
139 }
140
141 /**
Thomas Vachuska50ec1af2015-06-02 00:42:52 -0700142 * Registers a new step record.
143 *
144 * @param event step event
145 */
146 private synchronized void add(StepEvent event) {
147 events.add(event);
148 statusMap.put(event.name(), event.status());
149 }
150
151 /**
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700152 * Loads the states from disk.
153 */
154 private void load() {
Thomas Vachuska50ec1af2015-06-02 00:42:52 -0700155 try {
156 PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
157 cfg.getKeys().forEachRemaining(prop -> add(StepEvent.fromString(cfg.getString(prop))));
158 cfg.save();
159 } catch (ConfigurationException e) {
160 print("Unable to store file %s", storeFile);
161 }
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700162 }
163
164 /**
165 * Saves the states to disk.
166 */
167 private void save() {
168 try {
169 PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
Thomas Vachuska50ec1af2015-06-02 00:42:52 -0700170 events.forEach(event -> cfg.setProperty("T" + event.time(), event.toString()));
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700171 cfg.save();
172 } catch (ConfigurationException e) {
173 print("Unable to store file %s", storeFile);
174 }
175 }
176
Thomas Vachuskaa48e3d12015-06-02 09:43:29 -0700177 /**
178 * Removes all scenario log files.
179 */
180 private void removeLogs() {
181 File[] logFiles = logDir.listFiles();
182 if (logFiles != null && logFiles.length > 0) {
183 for (File file : logFiles) {
184 if (!file.delete()) {
185 print("Unable to delete log file %s", file);
186 }
187 }
188 }
189 }
190
Thomas Vachuskaf9c84362015-04-15 11:20:45 -0700191}