1 package org.whatsitcalled.webflange.webapp;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.List;
6
7 import org.apache.commons.io.IOUtils;
8 import org.apache.log4j.Logger;
9 import org.apache.wicket.AttributeModifier;
10 import org.apache.wicket.Page;
11 import org.apache.wicket.PageParameters;
12 import org.apache.wicket.ajax.AjaxRequestTarget;
13 import org.apache.wicket.ajax.markup.html.AjaxLink;
14 import org.apache.wicket.behavior.SimpleAttributeModifier;
15 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
16 import org.apache.wicket.markup.html.basic.Label;
17 import org.apache.wicket.markup.html.form.ChoiceRenderer;
18 import org.apache.wicket.markup.html.form.DropDownChoice;
19 import org.apache.wicket.markup.html.form.Form;
20 import org.apache.wicket.markup.html.form.RequiredTextField;
21 import org.apache.wicket.markup.html.form.TextArea;
22 import org.apache.wicket.markup.html.form.TextField;
23 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
24 import org.apache.wicket.markup.html.link.Link;
25 import org.apache.wicket.markup.html.panel.Panel;
26 import org.apache.wicket.markup.repeater.Item;
27 import org.apache.wicket.markup.repeater.data.DataView;
28 import org.apache.wicket.markup.repeater.data.IDataProvider;
29 import org.apache.wicket.model.AbstractReadOnlyModel;
30 import org.apache.wicket.model.CompoundPropertyModel;
31 import org.apache.wicket.model.IModel;
32 import org.apache.wicket.model.Model;
33 import org.apache.wicket.model.PropertyModel;
34 import org.whatsitcalled.webflange.ResourceFactory;
35 import org.whatsitcalled.webflange.model.LoadTest;
36 import org.whatsitcalled.webflange.model.LoadTestDAO;
37 import org.whatsitcalled.webflange.model.ProjectDAO;
38 import org.whatsitcalled.webflange.model.Script;
39 import org.whatsitcalled.webflange.model.ScriptDAO;
40 import org.whatsitcalled.webflange.service.LoadTestRunningException;
41 import org.whatsitcalled.webflange.webapp.model.LoadTestDataProvider;
42
43 public class TestPanel extends Panel {
44 AddTestForm testForm;
45
46 private static final Logger LOGGER = Logger.getLogger(TestPanel.class);
47
48 public TestPanel(String id) {
49 super(id);
50
51 add(new Link("newTest") {
52 public void onClick() {
53 testForm.setVisible(true);
54 setTest(getNewLoadTest());
55 }
56 });
57
58 add(new TestDataView("tests", new LoadTestDataProvider()));
59
60
61 testForm = new AddTestForm("addTestForm", new CompoundPropertyModel(
62 getTest()));
63 testForm.setVisible(false);
64 add(testForm);
65 }
66
67 private LoadTest getTest() {
68 LoadTest test = (LoadTest) getModelObject();
69 if (test == null) {
70 test = getNewLoadTest();
71 setTest(test);
72 }
73 return test;
74 }
75
76 private void setTest(LoadTest test) {
77 setModel(new CompoundPropertyModel(test));
78 }
79
80 public void onModelChanged() {
81 if ((testForm != null) && this.getModel() != null) {
82 testForm.setModel(this.getModel());
83 }
84 }
85
86 public static final LoadTest getLoadTestForEditing(LoadTest test) {
87 LoadTest loadTest = ResourceFactory.getLoadTestDAO().getLoadTest(test.getId());
88 loadTest.setEnabled(false);
89 ResourceFactory.getLoadTestDAO().saveLoadTest(loadTest);
90
91 return loadTest;
92 }
93
94
95 protected final class TestDataView extends DataView {
96 protected TestDataView(String arg0, IDataProvider arg1) {
97 super(arg0, arg1);
98 }
99
100 protected void populateItem(final Item item) {
101 final LoadTest test = (LoadTest) item.getModelObject();
102
103
104 item.add(new Link("edit") {
105 public void onClick() {
106 testForm.setVisible(true);
107 LoadTest test = (LoadTest) getParent().getModelObject();
108 setTest(getLoadTestForEditing(test));
109
110 }
111 });
112
113
114 Link enableLink = new Link("enable") {
115 public void onClick() {
116 LoadTest test = (LoadTest) getParent().getModelObject();
117 if (test.getEnabled()) {
118 LOGGER.debug("Disabling LoadTest: " + test.getName());
119 test.setEnabled(false);
120 } else {
121 LOGGER.debug("Enabling LoadTest: " + test.getName());
122 test.setEnabled(true);
123 }
124 ResourceFactory.getLoadTestDAO().saveLoadTest(test);
125 }
126 };
127 enableLink.add(new Label("enable/disable", new Model() {
128 public Object getObject() {
129 return test.getEnabled() ? "disable" : "enable";
130 }
131 }));
132 item.add(enableLink);
133
134
135 Link deleteLink = new Link("delete") {
136 public void onClick() {
137 LoadTest test = (LoadTest) getParent().getModelObject();
138 try {
139 ResourceFactory.getLoadTestService().removeLoadTest(test.getId());
140 } catch (LoadTestRunningException e) {
141 LOGGER.error("Unable to delete test.");
142 error(test.getName() + " is enabled or running and cannot be deleted!");
143 }
144 }
145 };
146 deleteLink.add(new SimpleAttributeModifier(
147 "onclick", "return confirm('Delete test " + test.getName() + "?');"));
148
149 item.add(deleteLink);
150
151
152 Link runLink = new Link("runNow") {
153 public void onClick() {
154 LoadTest test = (LoadTest) getParent().getModelObject();
155 ResourceFactory.getGrinderTestRunner().runAsThread(test);
156 }
157 };
158 runLink.add(new SimpleAttributeModifier(
159 "onclick", "return confirm('Run test " + test.getName() + "?');"));
160 item.add(runLink);
161
162
163 item.add(new BookmarkablePageLink("results", HomePage.class, new PageParameters("testId=" + test.getId())));
164
165 item.add(new Label("project", test.getProjectName()));
166 item.add(new Label("test", test.getName()));
167 item.add(new Label("script", test.getScriptName()));
168 item.add(new Label("frequency", test.getFrequency()));
169
170 item.add(new AttributeModifier("class", true,
171 new AbstractReadOnlyModel() {
172 public Object getObject() {
173 return (item.getIndex() % 2 == 1) ? "even" : "odd";
174 }
175 }));
176 }
177 }
178
179 protected final class AddTestForm extends Form {
180
181
182
183
184
185
186 public AddTestForm(final String id, IModel model) {
187
188
189 super(id, model);
190 add(getProjectChooser());
191 add(new RequiredTextField("name"));
192 addScriptView();
193 add(getScriptChooser());
194 TextField cronTextField = new TextField("frequency");
195
196 cronTextField.add(new CronValidator("Invalid cron expression in Frequency field."));
197 add(cronTextField);
198 add(new Label("contextVars", getContextVars()));
199 add(new TextArea("properties"));
200 add(new TextArea("description"));
201
202 final ModalWindow cronHelp;
203 add(cronHelp = new ModalWindow("cronHelp"));
204
205 cronHelp.setContent(new CronHelpPanel(cronHelp.getContentId()));
206 cronHelp.setTitle("Cron Expressions");
207 cronHelp.setCookieName("cronHelp");
208
209 add(new AjaxLink("showCronHelp") {
210 public void onClick(AjaxRequestTarget target) {
211 cronHelp.show(target);
212 }
213 });
214
215 }
216
217 private void addScriptView() {
218
219 final ModalWindow viewScript = new ModalWindow("viewScript");
220
221 add(viewScript);
222
223 add(new AjaxLink("showScript") {
224 public void onClick(AjaxRequestTarget target) {
225 final Script script = getTest().getScript();
226 viewScript.setTitle(script.getName());
227 viewScript.setCookieName("viewScript");
228 viewScript.setPageMapName("viewScript");
229
230 viewScript.setPageCreator(new ModalWindow.PageCreator() {
231 public Page createPage() {
232 return new ScriptViewPage(script, viewScript);
233 }
234 });
235 viewScript.show(target);
236 }
237 });
238 }
239
240 private DropDownChoice getProjectChooser() {
241 ProjectDAO dao = ResourceFactory.getProjectDAO();
242 List projects = dao.getProjects();
243 DropDownChoice ddc = new DropDownChoice("project",
244 new PropertyModel(getModelObject(), "project"), projects,
245 new ChoiceRenderer("name", "id"));
246 ddc.add(new ChoiceRequiredValidator("You must select a project."));
247 return ddc;
248 }
249
250 private DropDownChoice getScriptChooser() {
251 ScriptDAO dao = ResourceFactory.getScriptDAO();
252 List scripts = dao.getScripts();
253 DropDownChoice ddc = new DropDownChoice("script",
254 new PropertyModel(getModelObject(), "script"), scripts,
255 new ChoiceRenderer("name", "id"));
256 ddc.add(new ChoiceRequiredValidator("You must select a script."));
257 return ddc;
258 }
259
260
261
262
263 public final void onSubmit() {
264 final LoadTest test = (LoadTest) getModelObject();
265 LoadTestDAO dao = ResourceFactory.getLoadTestDAO();
266 dao.saveLoadTest(test);
267 this.setModel(new CompoundPropertyModel(getNewLoadTest()));
268 this.setVisible(false);
269
270 }
271
272 @Override
273 protected void onModelChanged() {
274 super.onModelChanged();
275
276
277 remove("project");
278 add(getProjectChooser());
279 remove("script");
280 add(getScriptChooser());
281 }
282
283 private String getContextVars() {
284 List<String> vars = ResourceFactory.getGrinderTestRunner().getContextVars();
285 StringBuffer buf = new StringBuffer();
286 for(String var:vars) {
287 buf.append("${");
288 buf.append(var);
289 buf.append("}\n");
290 }
291
292
293 return buf.toString();
294 }
295 }
296
297 protected class CronHelpPanel extends Panel {
298
299 public CronHelpPanel(String arg0) {
300 super(arg0);
301
302 }
303 }
304
305 LoadTest getNewLoadTest() {
306 return ResourceFactory.getLoadTestService().createLoadTest();
307 }
308
309 }