source: trunk/autoquest-htmlmonitor-test/src/test/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorTest.java @ 1069

Last change on this file since 1069 was 1069, checked in by pharms, 11 years ago
  • support of new HTML logging format
File size: 23.0 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.htmlmonitor;
16
17import static org.junit.Assert.*;
18
19import java.io.File;
20import java.util.Collection;
21import java.util.Iterator;
22import java.util.List;
23
24import org.apache.http.HttpEntity;
25import org.apache.http.HttpResponse;
26import org.apache.http.client.methods.HttpPost;
27import org.apache.http.entity.ContentType;
28import org.apache.http.entity.StringEntity;
29import org.apache.http.impl.client.DefaultHttpClient;
30import org.junit.After;
31import org.junit.Before;
32import org.junit.Test;
33
34import de.ugoe.cs.autoquest.eventcore.Event;
35import de.ugoe.cs.autoquest.eventcore.IEventType;
36import de.ugoe.cs.autoquest.eventcore.gui.KeyboardFocusChange;
37import de.ugoe.cs.autoquest.eventcore.gui.MouseButtonInteraction;
38import de.ugoe.cs.autoquest.eventcore.gui.MouseClick;
39import de.ugoe.cs.autoquest.eventcore.gui.MouseDoubleClick;
40import de.ugoe.cs.autoquest.eventcore.gui.Scroll;
41import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
42import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
43import de.ugoe.cs.autoquest.plugin.html.HTMLLogParser;
44import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLDocument;
45import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLPageElement;
46import de.ugoe.cs.autoquest.plugin.html.guimodel.HTMLServer;
47import de.ugoe.cs.util.console.TextConsole;
48
49/**
50 * <p>
51 * TODO comment
52 * </p>
53 *
54 * @author Patrick Harms
55 */
56public class HtmlMonitorTest {
57
58    /**
59     *
60     */
61    public static final TextConsole CONSOLE = new TextConsole();
62   
63    /**
64     *
65     */
66    private final static String LOG_FILE_DIR = "target/tmp/logfiles/";
67   
68    /**
69     *
70     */
71    private static final int PORT = 19098;
72
73    /**
74     *
75     */
76    private HtmlMonitor htmlMonitor;
77
78    /**
79     *
80     */
81    @Before
82    public void setUp() throws Exception {
83        htmlMonitor = new HtmlMonitor(new String[] { LOG_FILE_DIR, Integer.toString(PORT) });
84        htmlMonitor.init();
85        htmlMonitor.start();
86    }
87
88    /**
89     *
90     */
91    @After
92    public void tearDown() throws Exception {
93        if (htmlMonitor != null) {
94            try {
95                htmlMonitor.stop();
96            }
97            finally {
98                htmlMonitor = null;
99            }
100        }
101       
102        deleteFiles(new File(LOG_FILE_DIR));
103    }
104
105    /**
106     *
107     */
108    @Test
109    public void testOneSimpleMessage() throws Exception {
110        String clientId = "123";
111       
112        String message =
113            "{" +
114            "  \"message\": {" +
115            "    \"clientInfos\": {" +
116            "      \"clientId\":\"" + clientId + "\"," +
117            "      \"userAgent\":\"Agent\"," +
118            "      \"title\":\"Title\"," +
119            "      \"url\":\"http://host/path\"" +
120            "    }," +
121            "    \"guiModel\": {" +
122            "      \"tagName\":\"html\"," +
123            "      \"index\":\"0\"," +
124            "      \"children\":" +
125            "      [ {" +
126            "          \"tagName\":\"head\"," +
127            "          \"index\":\"0\"," +
128            "        }," +
129            "        {" +
130            "          \"tagName\":\"body\"," +
131            "          \"htmlId\":\"gsr\"," +
132            "        }" +
133            "      ]" +
134            "    }," +
135            "    \"events\":" +
136            "    [ {" +
137            "        \"time\":\"12345\"," +
138            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
139            "        \"eventType\":\"onclick\"" +
140            "        \"coordinates\": [\"194\", \"7\"]" +
141            "      }" +
142            "    ]" +
143            "  }" +
144            "}";
145
146        sendMessageAndAssertResponse(message);
147       
148        htmlMonitor.stop();
149        htmlMonitor = null;
150
151        File logFile = new File(LOG_FILE_DIR + File.separator + clientId + File.separator +
152                                "htmlmonitor_" + clientId + "_000.log");
153       
154        assertTrue(logFile.exists());
155       
156        HTMLLogParser parser = new HTMLLogParser();
157       
158        parser.parseFile(logFile);
159       
160        // check the GUI model
161        GUIModel guiModel = parser.getGuiModel();
162        assertNotNull(guiModel);
163       
164        List<IGUIElement> nodes = guiModel.getRootElements();
165        assertNotNull(nodes);
166        assertEquals(1, nodes.size());
167       
168        // get server node
169        IGUIElement node = nodes.get(0);
170        assertNotNull(node);
171        assertTrue(node instanceof HTMLServer);
172        assertEquals("HTML", node.getPlatform());
173        assertFalse(node.isUsed());
174       
175        nodes = guiModel.getChildren(node);
176        assertNotNull(nodes);
177        assertEquals(1, nodes.size());
178       
179        // get document node
180        node = nodes.get(0);
181        assertNotNull(node);
182        assertTrue(node instanceof HTMLDocument);
183        assertEquals("HTML", node.getPlatform());
184        assertFalse(node.isUsed());
185       
186        nodes = guiModel.getChildren(node);
187        assertNotNull(nodes);
188        assertEquals(1, nodes.size());
189       
190        // get html node
191        node = nodes.get(0);
192        assertNotNull(node);
193        assertTrue(node instanceof HTMLPageElement);
194        assertEquals("HTML", node.getPlatform());
195        assertFalse(node.isUsed());
196       
197        nodes = guiModel.getChildren(node);
198        assertNotNull(nodes);
199        assertEquals(1, nodes.size()); // only one child as the head tag should have been ignored
200       
201        // get body node
202        node = nodes.get(0);
203        assertNotNull(node);
204        assertTrue(node instanceof HTMLPageElement);
205        assertEquals("HTML", node.getPlatform());
206        assertTrue(node.isUsed());
207
208        nodes = guiModel.getChildren(node);
209        assertNotNull(nodes);
210        assertEquals(0, nodes.size());
211       
212        // check the sequences
213        Collection<List<Event>> sequences = parser.getSequences();
214       
215        assertNotNull(sequences);
216       
217        Iterator<List<Event>> iterator = sequences.iterator();
218        assertTrue(iterator.hasNext());
219       
220        List<Event> sequence = iterator.next();
221        assertFalse(iterator.hasNext());
222       
223        assertNotNull(sequence);
224        assertEquals(1, sequence.size());
225       
226        assertEvent(sequence.get(0), 12345, MouseClick.class, node, 194, 7);
227    }
228
229    /**
230     *
231     */
232    @Test
233    public void testSeveralMessagesInOneSession() throws Exception {
234        String clientId = "123";
235       
236        String message =
237            "{" +
238            "  \"message\": {" +
239            "    \"clientInfos\": {" +
240            "      \"clientId\":\"" + clientId + "\"," +
241            "      \"userAgent\":\"Agent\"," +
242            "      \"title\":\"Title\"," +
243            "      \"url\":\"http://host/path\"" +
244            "    }," +
245            "    \"guiModel\": {" +
246            "      \"tagName\":\"html\"," +
247            "      \"index\":\"0\"," +
248            "      \"children\":" +
249            "      [ {" +
250            "          \"tagName\":\"head\"," +
251            "          \"index\":\"0\"," +
252            "        }," +
253            "        {" +
254            "          \"tagName\":\"body\"," +
255            "          \"htmlId\":\"gsr\"," +
256            "          \"children\":" +
257            "          [ {" +
258            "              \"tagName\":\"input_button\"," +
259            "              \"htmlId\":\"input1\"," +
260            "            }," +
261            "            {" +
262            "              \"tagName\":\"input_button\"," +
263            "              \"htmlId\":\"input2\"," +
264            "            }," +
265            "            {" +
266            "              \"tagName\":\"input_button\"," +
267            "              \"htmlId\":\"input3\"," +
268            "            }," +
269            "            {" +
270            "              \"tagName\":\"input_button\"," +
271            "              \"htmlId\":\"input4\"," +
272            "            }," +
273            "            {" +
274            "              \"tagName\":\"input_button\"," +
275            "              \"htmlId\":\"input5\"," +
276            "            }," +
277            "            {" +
278            "              \"tagName\":\"input_button\"," +
279            "              \"htmlId\":\"input6\"," +
280            "            }," +
281            "            {" +
282            "              \"tagName\":\"input_button\"," +
283            "              \"htmlId\":\"input7\"," +
284            "            }," +
285            "            {" +
286            "              \"tagName\":\"input_button\"," +
287            "              \"htmlId\":\"input8\"," +
288            "            }," +
289            "            {" +
290            "              \"tagName\":\"input_button\"," +
291            "              \"htmlId\":\"input9\"," +
292            "            }," +
293            "            {" +
294            "              \"tagName\":\"input_button\"," +
295            "              \"htmlId\":\"input10\"," +
296            "            }," +
297            "          ]" +
298            "        }" +
299            "      ]" +
300            "    }," +
301            "    \"events\":" +
302            "    [ {" +
303            "        \"time\":\"1\"," +
304            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input1)\"," +
305            "        \"eventType\":\"onclick\"," +
306            "        \"coordinates\": [\"194\", \"7\"]" +
307            "      }," +
308            "      {" +
309            "        \"time\":\"2\"," +
310            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input2)\"," +
311            "        \"eventType\":\"ondblclick\"," +
312            "        \"coordinates\": [\"194\", \"7\"]" +
313            "      }," +
314            "      {" +
315            "        \"time\":\"3\"," +
316            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input3)\"," +
317            "        \"eventType\":\"onfocus\"" +
318            "      }," +
319            "      {" +
320            "        \"time\":\"4\"," +
321            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input4)\"," +
322            "        \"eventType\":\"onclick\"," +
323            "        \"coordinates\": [\"125\", \"14\"]" +
324            "      }," +
325            "      {" +
326            "        \"time\":\"5\"," +
327            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input5)\"," +
328            "        \"eventType\":\"onfocus\"" +
329            "      }," +
330            "      {" +
331            "        \"time\":\"6\"," +
332            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input6)\"," +
333            "        \"eventType\":\"onfocus\"" +
334            "      }," +
335            "      {" +
336            "        \"time\":\"7\"," +
337            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input7)\"," +
338            "        \"eventType\":\"onfocus\"" +
339            "      }," +
340            "      {" +
341            "        \"time\":\"8\"," +
342            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input8)\"," +
343            "        \"eventType\":\"onclick\"," +
344            "        \"coordinates\": [\"255\", \"4\"]" +
345            "      }," +
346            "      {" +
347            "        \"time\":\"9\"," +
348            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
349            "        \"eventType\":\"onscroll\"," +
350            "        \"scrollPosition\": [\"23\", \"567\"]" +
351            "      }," +
352            "      {" +
353            "        \"time\":\"10\"," +
354            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input10)\"," +
355            "        \"eventType\":\"onclick\"," +
356            "        \"coordinates\": [\"516\", \"154\"]" +
357            "      }" +
358            "    ]" +
359            "  }" +
360            "}";
361 
362        sendMessageAndAssertResponse(message);
363       
364        htmlMonitor.stop();
365        htmlMonitor = null;
366
367        File logFile = new File(LOG_FILE_DIR + File.separator + clientId + File.separator +
368                                "htmlmonitor_" + clientId + "_000.log");
369       
370        assertTrue(logFile.exists());
371       
372        HTMLLogParser parser = new HTMLLogParser();
373       
374        parser.parseFile(logFile);
375       
376        // check the GUI model
377        GUIModel guiModel = parser.getGuiModel();
378        assertNotNull(guiModel);
379       
380        List<IGUIElement> nodes = guiModel.getRootElements();
381        assertNotNull(nodes);
382        assertEquals(1, nodes.size());
383       
384        // get server node
385        IGUIElement node = nodes.get(0);
386        assertNotNull(node);
387        assertTrue(node instanceof HTMLServer);
388        assertEquals("HTML", node.getPlatform());
389        assertFalse(node.isUsed());
390       
391        nodes = guiModel.getChildren(node);
392        assertNotNull(nodes);
393        assertEquals(1, nodes.size());
394       
395        // get document node
396        node = nodes.get(0);
397        assertNotNull(node);
398        assertTrue(node instanceof HTMLDocument);
399        assertEquals("HTML", node.getPlatform());
400        assertFalse(node.isUsed());
401       
402        nodes = guiModel.getChildren(node);
403        assertNotNull(nodes);
404        assertEquals(1, nodes.size());
405       
406        // get html node
407        node = nodes.get(0);
408        assertNotNull(node);
409        assertTrue(node instanceof HTMLPageElement);
410        assertEquals("HTML", node.getPlatform());
411        assertFalse(node.isUsed());
412       
413        nodes = guiModel.getChildren(node);
414        assertNotNull(nodes);
415        assertEquals(1, nodes.size()); // only one child as the head tag should have been ignored
416       
417        // get body node
418        IGUIElement body = nodes.get(0);
419        assertNotNull(body);
420        assertTrue(body instanceof HTMLPageElement);
421        assertEquals("HTML", body.getPlatform());
422        assertTrue(body.isUsed());
423
424        nodes = guiModel.getChildren(body);
425        assertNotNull(nodes);
426        assertEquals(10, nodes.size());
427       
428        // get input nodes
429        for (int i = 0; i < nodes.size(); i++) {
430            node = nodes.get(i);
431            assertNotNull(node);
432            assertTrue(node instanceof HTMLPageElement);
433            assertEquals("HTML", node.getPlatform());
434           
435            if (i != 8) {
436                assertTrue(node.isUsed());
437            }
438            else {
439                assertFalse(node.isUsed());
440            }
441
442            assertNotNull(guiModel.getChildren(node));
443            assertEquals(0, guiModel.getChildren(node).size());
444        }
445       
446        // check the sequences
447        Collection<List<Event>> sequences = parser.getSequences();
448       
449        assertNotNull(sequences);
450       
451        Iterator<List<Event>> iterator = sequences.iterator();
452        assertTrue(iterator.hasNext());
453       
454        List<Event> sequence = iterator.next();
455        assertFalse(iterator.hasNext());
456       
457        assertNotNull(sequence);
458        assertEquals(10, sequence.size());
459       
460        assertEvent(sequence.get(0), 1, MouseClick.class, nodes.get(0), 194, 7);
461        assertEvent(sequence.get(1), 2, MouseDoubleClick.class, nodes.get(1), 194, 7);
462        assertEvent(sequence.get(2), 3, KeyboardFocusChange.class, nodes.get(2), 0, 0);
463        assertEvent(sequence.get(3), 4, MouseClick.class, nodes.get(3), 125, 14);
464        assertEvent(sequence.get(4), 5, KeyboardFocusChange.class, nodes.get(4), 0, 0);
465        assertEvent(sequence.get(5), 6, KeyboardFocusChange.class, nodes.get(5), 0, 0);
466        assertEvent(sequence.get(6), 7, KeyboardFocusChange.class, nodes.get(6), 0, 0);
467        assertEvent(sequence.get(7), 8, MouseClick.class, nodes.get(7), 255, 4);
468        assertEvent(sequence.get(8), 9, Scroll.class, body, 0, 0);
469        assertEvent(sequence.get(9), 10, MouseClick.class, nodes.get(9), 516, 154);
470
471    }
472
473    /**
474     *
475     */
476    @Test
477    public void testSeveralSessions() throws Exception {
478        String clientId = "123";
479       
480        String message =
481            "{" +
482            "  \"message\": {" +
483            "    \"clientInfos\": {" +
484            "      \"clientId\":\"" + clientId + "\"," +
485            "      \"userAgent\":\"Agent\"," +
486            "      \"title\":\"Title\"," +
487            "      \"url\":\"http://host/path\"" +
488            "    }," +
489            "    \"guiModel\": {" +
490            "      \"tagName\":\"html\"," +
491            "      \"index\":\"0\"," +
492            "      \"children\":" +
493            "      [ {" +
494            "          \"tagName\":\"head\"," +
495            "          \"index\":\"0\"," +
496            "        }," +
497            "        {" +
498            "          \"tagName\":\"body\"," +
499            "          \"htmlId\":\"gsr\"," +
500            "        }" +
501            "      ]" +
502            "    }," +
503            "    \"events\":" +
504            "    [ {" +
505            "        \"time\":\"12345\"," +
506            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
507            "        \"eventType\":\"onclick\"" +
508            "        \"coordinates\": [\"194\", \"7\"]" +
509            "      }" +
510            "    ]" +
511            "  }" +
512            "}";
513
514        sendMessageAndAssertResponse(message);
515       
516        int numberOfSessions = 10;
517        for (int i = 0; i < numberOfSessions; i++) {
518            htmlMonitor.stop();
519            htmlMonitor = new HtmlMonitor(new String[] { LOG_FILE_DIR, Integer.toString(PORT) });
520            htmlMonitor.init();
521            htmlMonitor.start();
522            sendMessageAndAssertResponse(message);
523        }
524       
525        htmlMonitor.stop();
526        htmlMonitor = null;
527       
528        HTMLLogParser parser = new HTMLLogParser();
529       
530        // assert 9 already rotated log files
531        for (int i = 0; i < numberOfSessions; i++) {
532            File logFile = new File(LOG_FILE_DIR + File.separator + clientId + File.separator +
533                                    "htmlmonitor_" + clientId + "_00" + i + ".log");
534       
535            assertTrue(logFile.exists());
536       
537            parser.parseFile(logFile);
538        }
539
540        // check the GUI model
541        GUIModel guiModel = parser.getGuiModel();
542        assertNotNull(guiModel);
543       
544        List<IGUIElement> nodes = guiModel.getRootElements();
545        assertNotNull(nodes);
546        assertEquals(1, nodes.size());
547       
548        // get server node
549        IGUIElement node = nodes.get(0);
550        assertNotNull(node);
551        assertTrue(node instanceof HTMLServer);
552        assertEquals("HTML", node.getPlatform());
553        assertFalse(node.isUsed());
554       
555        nodes = guiModel.getChildren(node);
556        assertNotNull(nodes);
557        assertEquals(1, nodes.size());
558       
559        // get document node
560        node = nodes.get(0);
561        assertNotNull(node);
562        assertTrue(node instanceof HTMLDocument);
563        assertEquals("HTML", node.getPlatform());
564        assertFalse(node.isUsed());
565       
566        nodes = guiModel.getChildren(node);
567        assertNotNull(nodes);
568        assertEquals(1, nodes.size());
569       
570        // get html node
571        node = nodes.get(0);
572        assertNotNull(node);
573        assertTrue(node instanceof HTMLPageElement);
574        assertEquals("HTML", node.getPlatform());
575        assertFalse(node.isUsed());
576       
577        nodes = guiModel.getChildren(node);
578        assertNotNull(nodes);
579        assertEquals(1, nodes.size()); // only one child as the head tag should have been ignored
580       
581        // get body node
582        node = nodes.get(0);
583        assertNotNull(node);
584        assertTrue(node instanceof HTMLPageElement);
585        assertEquals("HTML", node.getPlatform());
586        assertTrue(node.isUsed());
587
588        nodes = guiModel.getChildren(node);
589        assertNotNull(nodes);
590        assertEquals(0, nodes.size());
591       
592        // check the sequences
593        Collection<List<Event>> sequences = parser.getSequences();
594       
595        assertNotNull(sequences);
596        assertEquals(numberOfSessions, sequences.size());
597       
598        Iterator<List<Event>> iterator = sequences.iterator();
599       
600        while (iterator.hasNext()) {
601            List<Event> sequence = iterator.next();
602       
603            assertNotNull(sequence);
604            assertEquals(1, sequence.size());
605       
606            assertEvent(sequence.get(0), 12345, MouseClick.class, node, 194, 7);
607        }
608    }
609
610    /**
611     * <p>
612     * TODO: comment
613     * </p>
614     *
615     * @param message
616     */
617    private void sendMessageAndAssertResponse(String message) throws Exception {
618        DefaultHttpClient httpclient = new DefaultHttpClient();
619        HttpPost httpPost = new HttpPost("http://localhost:" + PORT + "/");
620        HttpEntity entity = new StringEntity(message, ContentType.APPLICATION_JSON);
621        httpPost.setEntity(entity);
622       
623        try {
624            HttpResponse response = httpclient.execute(httpPost);
625           
626            // the monitor always returns 200 without any additional information. The client must
627            // never get more or less information. This is especially important for preventing
628            // hackers from finding out more
629            assertEquals(200, response.getStatusLine().getStatusCode());
630            assertTrue
631                ((response.getEntity() == null) || (response.getEntity().getContentLength() == 0));
632        }
633        finally {
634            httpPost.releaseConnection();
635        }
636    }
637
638    /**
639     *
640     */
641    private void assertEvent(Event                       event,
642                             int                         timestamp,
643                             Class<? extends IEventType> eventType,
644                             IGUIElement                 eventTarget,
645                             int                         xCoordinate,
646                             int                         yCoordinate)
647    {
648        assertEquals(timestamp, event.getTimestamp());
649        assertTrue(eventType.isInstance(event.getType()));
650        assertEquals(eventTarget, event.getTarget());
651       
652        if (event.getType() instanceof MouseButtonInteraction) {
653            assertEquals(xCoordinate, ((MouseButtonInteraction) event.getType()).getX());
654            assertEquals(yCoordinate, ((MouseButtonInteraction) event.getType()).getY());
655        }
656    }
657
658    /**
659     * <p>
660     * TODO: comment
661     * </p>
662     *
663     * @param file
664     */
665    private void deleteFiles(File file) {
666        if (file.exists()) {
667            if (file.isDirectory()) {
668                for (File child : file.listFiles()) {
669                    deleteFiles(child);
670                }
671            }
672           
673            try {
674                file.delete();
675            }
676            catch (Exception e) {
677                // ignore and delete as much as possible
678            }
679        }
680    }
681
682}
Note: See TracBrowser for help on using the repository browser.