source: trunk/autoquest-htmlmonitor-test/src/test/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServerTest.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: 22.4 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 org.apache.http.HttpEntity;
20import org.apache.http.HttpResponse;
21import org.apache.http.client.methods.HttpPost;
22import org.apache.http.entity.ContentType;
23import org.apache.http.entity.StringEntity;
24import org.apache.http.impl.client.DefaultHttpClient;
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28
29import de.ugoe.cs.util.console.TextConsole;
30
31/**
32 * <p>
33 * TODO comment
34 * </p>
35 *
36 * @author Patrick Harms
37 */
38public class HtmlMonitorServerTest implements HtmlMonitorMessageListener {
39   
40    /**
41     *
42     */
43    public static final TextConsole CONSOLE = new TextConsole();
44   
45    /**
46     *
47     */
48    private static final int PORT = 19098;
49
50    /**
51     *
52     */
53    private HtmlEvent[] events;
54
55    /**
56     *
57     */
58    private HtmlGUIElement guiStructure;
59
60    /**
61     *
62     */
63    private String eventHandlingError;
64
65    /**
66     *
67     */
68    private HtmlMonitorServer server;
69
70    /**
71     *
72     */
73    @Before
74    public void setUp() throws Exception {
75        server = new HtmlMonitorServer(PORT, this);
76        server.init();
77        server.start();
78    }
79   
80    /**
81     *
82     */
83    @After
84    public void tearDown() throws Exception {
85        events = null;
86        eventHandlingError = null;
87
88        if (server != null) {
89            try {
90                server.stop();
91            }
92            finally {
93                server = null;
94            }
95        }
96    }
97   
98
99    /**
100     *
101     */
102    @Test
103    public void testSimpleMessage() throws Exception {
104        String clientId = "123";
105       
106        String message =
107            "{" +
108            "  \"message\": {" +
109            "    \"clientInfos\": {" +
110            "      \"clientId\":\"" + clientId + "\"," +
111            "      \"userAgent\":\"Agent\"," +
112            "      \"title\":\"Title\"," +
113            "      \"url\":\"http://host/path\"" +
114            "    }," +
115            "    \"guiModel\": {" +
116            "      \"tagName\":\"html\"," +
117            "      \"index\":\"0\"," +
118            "      \"children\":" +
119            "      [ {" +
120            "          \"tagName\":\"head\"," +
121            "          \"index\":\"0\"," +
122            "        }," +
123            "        {" +
124            "          \"tagName\":\"body\"," +
125            "          \"htmlId\":\"gsr\"," +
126            "        }" +
127            "      ]" +
128            "    }," +
129            "    \"events\":" +
130            "    [ {" +
131            "        \"time\":\"12345\"," +
132            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
133            "        \"eventType\":\"onclick\"" +
134            "        \"coordinates\": [\"194\", \"7\"]" +
135            "      }" +
136            "    ]" +
137            "  }" +
138            "}";
139       
140        sendMessageAndAssertResponse(message);
141       
142        if (eventHandlingError != null) {
143            fail(eventHandlingError);
144        }
145       
146        // check the GUI structure
147        HtmlGUIElement parent = null;
148        HtmlGUIElement element = guiStructure;
149       
150        assertGuiElement(element, HtmlServer.class, parent, 1);
151       
152        parent = element;
153        element = parent.getChildren().get(0);
154        assertGuiElement(element, HtmlDocument.class, parent, 1);
155       
156        HtmlDocument document = (HtmlDocument) element;
157       
158        parent = element;
159        element = parent.getChildren().get(0);
160        assertGuiElement(element, HtmlPageElement.class, parent, 2);
161
162        parent = element;
163        element = parent.getChildren().get(0);
164        assertGuiElement(element, HtmlPageElement.class, parent, 0);
165        element = parent.getChildren().get(1);
166        assertGuiElement(element, HtmlPageElement.class, parent, 0);
167
168        // check the event
169        assertNotNull(events);
170        assertEquals(1, events.length);
171       
172        assertEvent(0, 12345, "/html[0]/body(htmlId=gsr)", element, document, "onclick",
173                    null, null, new Integer[] {194, 7},
174                    "Title", "Agent", "http://host/path", "123");
175       
176    }
177
178    /**
179     *
180     */
181    @Test
182    public void testComplexMessage() throws Exception {
183        String clientId = "123";
184       
185        String message =
186            "{" +
187            "  \"message\": {" +
188            "    \"clientInfos\": {" +
189            "      \"clientId\":\"" + clientId + "\"," +
190            "      \"userAgent\":\"Agent\"," +
191            "      \"title\":\"Title\"," +
192            "      \"url\":\"http://host/path\"" +
193            "    }," +
194            "    \"guiModel\": {" +
195            "      \"tagName\":\"html\"," +
196            "      \"index\":\"0\"," +
197            "      \"children\":" +
198            "      [ {" +
199            "          \"tagName\":\"head\"," +
200            "          \"index\":\"0\"," +
201            "        }," +
202            "        {" +
203            "          \"tagName\":\"body\"," +
204            "          \"htmlId\":\"gsr\"," +
205            "          \"children\":" +
206            "          [ {" +
207            "              \"tagName\":\"input_button\"," +
208            "              \"htmlId\":\"input1\"," +
209            "            }," +
210            "            {" +
211            "              \"tagName\":\"input_button\"," +
212            "              \"htmlId\":\"input2\"," +
213            "            }," +
214            "            {" +
215            "              \"tagName\":\"input_button\"," +
216            "              \"htmlId\":\"input3\"," +
217            "            }," +
218            "            {" +
219            "              \"tagName\":\"input_button\"," +
220            "              \"htmlId\":\"input4\"," +
221            "            }," +
222            "            {" +
223            "              \"tagName\":\"input_button\"," +
224            "              \"htmlId\":\"input5\"," +
225            "            }," +
226            "            {" +
227            "              \"tagName\":\"input_button\"," +
228            "              \"htmlId\":\"input6\"," +
229            "            }," +
230            "            {" +
231            "              \"tagName\":\"input_button\"," +
232            "              \"htmlId\":\"input7\"," +
233            "            }," +
234            "            {" +
235            "              \"tagName\":\"input_button\"," +
236            "              \"htmlId\":\"input8\"," +
237            "            }," +
238            "            {" +
239            "              \"tagName\":\"input_button\"," +
240            "              \"htmlId\":\"input9\"," +
241            "            }," +
242            "            {" +
243            "              \"tagName\":\"input_button\"," +
244            "              \"htmlId\":\"input10\"," +
245            "            }," +
246            "          ]" +
247            "        }" +
248            "      ]" +
249            "    }," +
250            "    \"events\":" +
251            "    [ {" +
252            "        \"time\":\"1\"," +
253            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input1)\"," +
254            "        \"eventType\":\"onclick\"," +
255            "        \"coordinates\": [\"194\", \"7\"]" +
256            "      }," +
257            "      {" +
258            "        \"time\":\"2\"," +
259            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input2)\"," +
260            "        \"eventType\":\"ondblclick\"," +
261            "        \"coordinates\": [\"194\", \"7\"]" +
262            "      }," +
263            "      {" +
264            "        \"time\":\"3\"," +
265            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input3)\"," +
266            "        \"eventType\":\"onfocus\"" +
267            "      }," +
268            "      {" +
269            "        \"time\":\"4\"," +
270            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input4)\"," +
271            "        \"eventType\":\"onclick\"," +
272            "        \"coordinates\": [\"125\", \"14\"]" +
273            "      }," +
274            "      {" +
275            "        \"time\":\"5\"," +
276            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input5)\"," +
277            "        \"eventType\":\"onfocus\"" +
278            "      }," +
279            "      {" +
280            "        \"time\":\"6\"," +
281            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input6)\"," +
282            "        \"eventType\":\"onfocus\"" +
283            "      }," +
284            "      {" +
285            "        \"time\":\"7\"," +
286            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input7)\"," +
287            "        \"eventType\":\"onfocus\"" +
288            "      }," +
289            "      {" +
290            "        \"time\":\"8\"," +
291            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input8)\"," +
292            "        \"eventType\":\"onclick\"," +
293            "        \"coordinates\": [\"255\", \"4\"]" +
294            "      }," +
295            "      {" +
296            "        \"time\":\"9\"," +
297            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
298            "        \"eventType\":\"onscroll\"," +
299            "        \"scrollPosition\": [\"23\", \"567\"]" +
300            "      }," +
301            "      {" +
302            "        \"time\":\"10\"," +
303            "        \"path\":\"/html[0]/body(htmlId=gsr)/input_button(htmlId=input10)\"," +
304            "        \"eventType\":\"onclick\"," +
305            "        \"coordinates\": [\"516\", \"154\"]" +
306            "      }" +
307            "    ]" +
308            "  }" +
309            "}";
310 
311        sendMessageAndAssertResponse(message);
312       
313        if (eventHandlingError != null) {
314            fail(eventHandlingError);
315        }
316       
317        // check the GUI structure
318        HtmlGUIElement parent = null;
319        HtmlGUIElement element = guiStructure;
320       
321        assertGuiElement(element, HtmlServer.class, parent, 1);
322       
323        parent = element;
324        element = parent.getChildren().get(0);
325        assertGuiElement(element, HtmlDocument.class, parent, 1);
326       
327        HtmlDocument document = (HtmlDocument) element;
328       
329        parent = element;
330        element = parent.getChildren().get(0);
331        assertGuiElement(element, HtmlPageElement.class, parent, 2);
332
333        parent = element;
334        element = parent.getChildren().get(0);
335        assertGuiElement(element, HtmlPageElement.class, parent, 0);
336        element = parent.getChildren().get(1);
337        assertGuiElement(element, HtmlPageElement.class, parent, 10);
338       
339        parent = element;
340        for (HtmlGUIElement child : parent.getChildren()) {
341            assertGuiElement(child, HtmlPageElement.class, parent, 0);
342        }
343
344        // check the events
345        assertNotNull(events);
346        assertEquals(10, events.length);
347
348        for (int i = 0; i < events.length; i++) {
349            String targetDOMPath;
350            HtmlGUIElement target;
351            Integer[] scrollPosition = null;
352           
353            if (i == 8) {
354                targetDOMPath = "/html[0]/body(htmlId=gsr)";
355                target = parent;
356                scrollPosition = new Integer[] { 23, 567 };
357            }
358            else {
359                targetDOMPath =
360                    "/html[0]/body(htmlId=gsr)/input_button(htmlId=input" + (i + 1) + ")";
361                target = parent.getChildren().get(i);
362            }
363           
364            String eventType;
365            if ((i == 1)) {
366                eventType = "ondblclick";
367            }
368            else if ((i == 2) || ((4 <= i) && (i <= 6))) {
369                eventType = "onfocus";
370            }
371            else if ((i == 8)) {
372                eventType = "onscroll";
373            }
374            else {
375                eventType = "onclick";
376            }
377           
378            assertNull("event " + i, events[i].getKey());
379           
380            Integer[] coordinates = null;
381            if (i <= 1) {
382                coordinates = new Integer[] { 194, 7 };
383            }
384            else if (i == 3) {
385                coordinates = new Integer[] { 125, 14 };
386            }
387            else if (i == 7) {
388                coordinates = new Integer[] { 255, 4 };
389            }
390            else if (i == 9) {
391                coordinates = new Integer[] { 516, 154 };
392            }
393           
394            assertEvent(i, i + 1, targetDOMPath, target, document, eventType,
395                        null, scrollPosition, coordinates,
396                        "Title", "Agent", "http://host/path", "123");
397           
398        }
399    }
400   
401    /**
402     *
403     */
404    @Test
405    public void testInvalidMessages() throws Exception {
406        String message = "}";
407       
408        sendMessageAndAssertResponse(message);
409           
410        if (eventHandlingError != null) {
411            fail(eventHandlingError);
412        }
413
414        assertNull(events);
415
416        message = "blaublbidalslkdjflqkerowercalksdjfdlkkjdjfk";
417       
418        sendMessageAndAssertResponse(message);
419           
420        if (eventHandlingError != null) {
421            fail(eventHandlingError);
422        }
423
424        assertNull(events);
425       
426        // the following message doesn't work because of the missing scroll position in the event
427        message =
428            "{" +
429            "  \"message\": {" +
430            "    \"clientInfos\": {" +
431            "      \"clientId\":\"123\"," +
432            "      \"userAgent\":\"Agent\"," +
433            "      \"title\":\"Title\"," +
434            "      \"url\":\"http://host/path\"" +
435            "    }," +
436            "    \"guiModel\": {" +
437            "      \"tagName\":\"html\"," +
438            "      \"index\":\"0\"," +
439            "      \"children\":" +
440            "      [ {" +
441            "          \"tagName\":\"head\"," +
442            "          \"index\":\"0\"," +
443            "        }," +
444            "        {" +
445            "          \"tagName\":\"body\"," +
446            "          \"htmlId\":\"gsr\"," +
447            "        }" +
448            "      ]" +
449            "    }," +
450            "    \"events\":" +
451            "    [ {" +
452            "        \"time\":\"9\"," +
453            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
454            "        \"eventType\":\"onscroll\"," +
455            "      }" +
456            "    ]" +
457            "  }" +
458            "}";
459       
460        sendMessageAndAssertResponse(message);
461       
462        if (eventHandlingError != null) {
463            fail(eventHandlingError);
464        }
465
466        assertNull(events);
467       
468        // the following message doesn't work because of the missing client id
469        message =
470            "{" +
471            "  \"message\": {" +
472            "    \"clientInfos\": {" +
473            "      \"userAgent\":\"Agent\"," +
474            "      \"title\":\"Title\"," +
475            "      \"url\":\"http://host/path\"" +
476            "    }," +
477            "    \"guiModel\": {" +
478            "      \"tagName\":\"html\"," +
479            "      \"index\":\"0\"," +
480            "      \"children\":" +
481            "      [ {" +
482            "          \"tagName\":\"head\"," +
483            "          \"index\":\"0\"," +
484            "        }," +
485            "        {" +
486            "          \"tagName\":\"body\"," +
487            "          \"htmlId\":\"gsr\"," +
488            "        }" +
489            "      ]" +
490            "    }," +
491            "    \"events\":" +
492            "    [ {" +
493            "        \"time\":\"12345\"," +
494            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
495            "        \"eventType\":\"onunload\"" +
496            "      }" +
497            "    ]" +
498            "  }" +
499            "}";
500       
501        sendMessageAndAssertResponse(message);
502       
503        if (eventHandlingError != null) {
504            fail(eventHandlingError);
505        }
506
507        assertNull(events);
508       
509        // the following message doesn't work because of the invalid time stamp
510        message =
511            "{" +
512            "  \"message\": {" +
513            "    \"clientInfos\": {" +
514            "      \"clientId\":\"123\"," +
515            "      \"userAgent\":\"Agent\"," +
516            "      \"title\":\"Title\"," +
517            "      \"url\":\"http://host/path\"" +
518            "    }," +
519            "    \"guiModel\": {" +
520            "      \"tagName\":\"html\"," +
521            "      \"index\":\"0\"," +
522            "      \"children\":" +
523            "      [ {" +
524            "          \"tagName\":\"head\"," +
525            "          \"index\":\"0\"," +
526            "        }," +
527            "        {" +
528            "          \"tagName\":\"body\"," +
529            "          \"htmlId\":\"gsr\"," +
530            "        }" +
531            "      ]" +
532            "    }," +
533            "    \"events\":" +
534            "    [ {" +
535            "        \"time\":\"blub\"," +
536            "        \"path\":\"/html[0]/body(htmlId=gsr)\"," +
537            "        \"eventType\":\"onunload\"" +
538            "      }" +
539            "    ]" +
540            "  }" +
541            "}";
542       
543        sendMessageAndAssertResponse(message);
544       
545        if (eventHandlingError != null) {
546            fail(eventHandlingError);
547        }
548
549        assertNull(events);
550       
551    }
552   
553    /* (non-Javadoc)
554     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitoringListener#handleEvents(de.ugoe.cs.autoquest.htmlmonitor.HtmlClientInfos, de.ugoe.cs.autoquest.htmlmonitor.HtmlEvent[])
555     */
556    @Override
557    public void handleMessage(HtmlClientInfos clientInfos,
558                              HtmlGUIElement  guiStructure,
559                              HtmlEvent[]     events)
560    {
561        if (clientInfos == null) {
562            eventHandlingError = "client infos were null";
563        }
564        else if (guiStructure == null) {
565            eventHandlingError = "gui structure was null";
566        }
567        else if (events == null) {
568            eventHandlingError = "events were null";
569        }
570        else {
571            for (HtmlEvent event : events) {
572                if (!clientInfos.equals(event.getClientInfos())) {
573                    eventHandlingError = "one of the events did not have a correct client info";
574                }
575            }
576           
577            this.events = events;
578            this.guiStructure = guiStructure;
579        }
580    }
581
582    /**
583     * <p>
584     * TODO: comment
585     * </p>
586     *
587     * @param message
588     */
589    private void sendMessageAndAssertResponse(String message) throws Exception {
590        DefaultHttpClient httpclient = new DefaultHttpClient();
591        HttpPost httpPost = new HttpPost("http://localhost:" + PORT + "/");
592        HttpEntity entity = new StringEntity(message, ContentType.APPLICATION_JSON);
593        httpPost.setEntity(entity);
594       
595        try {
596            HttpResponse response = httpclient.execute(httpPost);
597           
598            // the monitor always returns 200 without any additional information. The client must
599            // never get more or less information. This is especially important for preventing
600            // hackers from finding out more
601            assertEquals(200, response.getStatusLine().getStatusCode());
602            assertTrue
603                ((response.getEntity() == null) || (response.getEntity().getContentLength() == 0));
604        }
605        finally {
606            httpPost.releaseConnection();
607        }
608    }
609
610    /**
611     *
612     */
613    private void assertGuiElement(HtmlGUIElement                  element,
614                                  Class<? extends HtmlGUIElement> type,
615                                  HtmlGUIElement                  parent,
616                                  int                             noOfChildren)
617    {
618        assertTrue(type.isInstance(element));
619       
620        if (parent != null) {
621            assertEquals(parent.getId(), element.getParentId());
622        }
623        else {
624            assertNull(element.getParentId());
625        }
626       
627        assertNotNull(element.getId());
628       
629        if (noOfChildren > 0) {
630            assertNotNull(element.getChildren());
631            assertEquals(noOfChildren, element.getChildren().size());
632        }
633        else {
634            assertNull(element.getChildren());
635        }
636    }
637
638    /**
639     *
640     */
641    private void assertEvent(int            index,
642                             long           timestamp,
643                             String         targetDOMPath,
644                             HtmlGUIElement target,
645                             HtmlDocument   document,
646                             String         eventType,
647                             Integer        key,
648                             Integer[]      scrollPosition,
649                             Integer[]      coordinates,
650                             String         clientInfoTitle,
651                             String         clientInfoAgent,
652                             String         clientInfoURL,
653                             String         clientId)
654    {
655        assertEquals("event " + index, new Long(timestamp), events[index].getTime());
656        assertEquals("event " + index, targetDOMPath, events[index].getTargetDOMPath());
657        assertEquals("event " + index, target, events[index].getTarget());
658        assertEquals("event " + index, document, events[index].getTargetDocument());
659        assertEquals("event " + index, eventType, events[index].getEventType());
660       
661        assertEquals("event " + index, key, events[index].getKey());
662        assertArrayEquals("event " + index, scrollPosition, events[index].getScrollPosition());
663        assertArrayEquals("event " + index, coordinates, events[index].getCoordinates());
664       
665        assertEquals
666            ("event " + index, clientInfoTitle, events[index].getClientInfos().getTitle());
667        assertEquals
668            ("event " + index, clientInfoAgent, events[index].getClientInfos().getUserAgent());
669        assertEquals
670            ("event " + index, clientInfoURL, events[index].getClientInfos().getUrl().toString());
671        assertEquals
672            ("event " + index, clientId, events[index].getClientInfos().getClientId());
673    }
674
675}
Note: See TracBrowser for help on using the repository browser.