View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.chukwa.datacollection.agent.rest;
19  
20  import junit.framework.TestCase;
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.hadoop.chukwa.datacollection.agent.ChukwaAgent;
24  import org.springframework.mock.web.MockHttpServletRequest;
25  import org.springframework.mock.web.MockHttpServletResponse;
26  import org.mortbay.jetty.servlet.ServletHolder;
27  import org.mortbay.jetty.servlet.Context;
28  import org.mortbay.jetty.servlet.ServletHandler;
29  import org.mortbay.jetty.Server;
30  
31  import javax.servlet.ServletException;
32  import javax.servlet.Servlet;
33  import java.io.IOException;
34  import java.io.UnsupportedEncodingException;
35  
36  import com.sun.jersey.spi.container.servlet.ServletContainer;
37  
38  /**
39   * Tests the basic functionality of the AdaptorController.
40   */
41  public class TestAdaptorController extends TestCase {
42    protected Log log = LogFactory.getLog(getClass());
43  
44    Server jettyServer;
45    ChukwaAgent agent;
46    Servlet servlet;
47    MockHttpServletRequest request;
48    MockHttpServletResponse response;
49    StringBuilder sb;
50  
51    protected void setUp() throws Exception {
52      agent = new ChukwaAgent();
53  
54      ServletHolder servletHolder = new ServletHolder(ServletContainer.class);
55      servletHolder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
56              "com.sun.jersey.api.core.PackagesResourceConfig");
57      servletHolder.setInitParameter("com.sun.jersey.config.property.packages",
58              "org.apache.hadoop.chukwa.datacollection.agent.rest");
59      servletHolder.setServletHandler(new ServletHandler());
60  
61      jettyServer = new Server();
62  
63      Context root = new Context(jettyServer, "/foo/bar", Context.SESSIONS);
64      root.setAttribute("ChukwaAgent", agent);
65      root.addServlet(servletHolder, "/*");
66  
67      jettyServer.start();
68      jettyServer.setStopAtShutdown(true);
69  
70      servlet = servletHolder.getServlet();
71      request = new MockHttpServletRequest();
72      request.setContextPath("/foo/bar");
73  
74      response = new MockHttpServletResponse();
75      agent.processAddCommandE("add org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor SomeDataType 0");
76      sb = new StringBuilder();
77    }
78  
79    protected void tearDown() throws Exception {
80      agent.shutdown();
81      jettyServer.stop();
82    }
83  
84    public void testGetPlainText() throws IOException, ServletException {
85      request.setServletPath("/adaptor");
86      request.setRequestURI(request.getContextPath() + request.getServletPath());
87      request.setQueryString("viewType=text");
88      request.setMethod("GET");
89  
90      servlet.service(request, response);
91  
92      // assert response
93      assertTextResponse(response, 1);
94  
95      //assert agent
96      assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount());
97    }
98  
99    private void assertOccurs(String message, int occurances, String text, String match) {
100 
101     int index = -1;
102     for(int i = 0; i < occurances; i++) {
103       index = text.indexOf(match, index + 1);
104       assertTrue(message + ": " + text, index != -1);
105     }
106   }
107 
108   public void testGetXml() throws IOException, ServletException {
109     request.setServletPath("/adaptor");
110     request.setRequestURI(request.getContextPath() + request.getServletPath());
111     request.setQueryString("viewType=xml");
112     request.setMethod("GET");
113 
114     servlet.service(request, response);
115 
116     String responseContent = response.getContentAsString();
117 
118     // assert response
119     assertXmlResponse(response, 1);
120 
121     //assert agent
122     assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount());
123   }
124 
125   public void testGetInvalidViewType() throws IOException, ServletException {
126     request.setServletPath("/adaptor");
127     request.setRequestURI(request.getContextPath() + request.getServletPath());
128     request.setQueryString("viewType=unsupportedViewType");
129     request.setMethod("GET");
130 
131     servlet.service(request, response);
132 
133     // assert response
134     assertEquals("Unexpected response status", 400, response.getStatus());
135     assertEquals("Unexpected response content",
136             "Invalid viewType: unsupportedViewType", response.getContentAsString());
137   }
138 
139   public void testDeleteAdaptor() throws IOException, ServletException {
140     String adaptorId = agent.getAdaptorList().keySet().iterator().next();
141 
142     request.setServletPath("/adaptor/" + adaptorId);
143     request.setRequestURI(request.getContextPath() + request.getServletPath());
144 
145     //assert agent
146     assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount());
147     request.setMethod("DELETE");
148 
149     servlet.service(request, response);
150 
151     // assert response
152     assertEquals("Unexpected response status", 200, response.getStatus());
153 
154     //assert agent
155     assertEquals("Incorrect total number of adaptors", 0, agent.adaptorCount());
156   }
157 
158   public void testAddAdaptor() throws IOException, ServletException {
159     request.setServletPath("/adaptor");
160     request.setRequestURI(request.getContextPath() + request.getServletPath());
161     request.setContentType("application/json;charset=UTF-8");
162     request.setContent("{ \"DataType\" : \"SomeDataType\", \"AdaptorClass\" : \"org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor\", \"AdaptorParams\" : \"1000\", \"Offset\" : \"5555\" }".getBytes());
163 
164     //assert agent
165     assertEquals("Incorrect total number of adaptors", 1, agent.adaptorCount());
166     String initialAdaptorId = agent.getAdaptorList().keySet().iterator().next();
167 
168     request.setMethod("POST");
169 
170     servlet.service(request, response);
171 
172     // assert response
173     String responseContent = assertXmlResponse(response, 1);
174     String newAdaptorId = null;
175     for (String id : agent.getAdaptorList().keySet()) {
176       if (id != initialAdaptorId) {
177         newAdaptorId = id;
178         break;
179       }
180     }
181 
182     //assert agent
183     assertEquals("Incorrect total number of adaptors", 2, agent.adaptorCount());
184 
185     assertOccurs("Response did not contain adaptorId", 1, responseContent, newAdaptorId);
186 
187     //assert agent
188     assertEquals("Incorrect total number of adaptors", 2, agent.adaptorCount());
189 
190     // fire a doGet to assert that the servlet shows 2 adaptors
191     request.setQueryString("viewType=text");
192     request.setMethod("GET");
193     request.setContentType(null);
194     request.setContent(null);
195 
196     servlet.service(request, response);
197 
198     // assert response
199     assertTextResponse(response, 2);
200   }
201 
202   private String assertTextResponse(MockHttpServletResponse response,
203                                   int adaptorCount)
204                                   throws UnsupportedEncodingException {
205     String responseContent = response.getContentAsString();
206 
207     assertEquals("Unexpected response status", 200, response.getStatus());
208     //Content it correct when executed via an HTTP client, but it doesn't seem
209     //to get set by the servlet
210     //assertEquals("Unexpected content type", "text/plain;charset=UTF-8",
211     //            response.getContentType());
212     assertOccurs("Response text doesn't include correct adaptor_count", 1,
213             responseContent, "adaptor_count: " + adaptorCount);
214     assertOccurs("Response text doesn't include adaptor class",
215             adaptorCount, responseContent,
216             "adaptor_class: org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor");
217     assertOccurs("Response text doesn't include data type",
218             adaptorCount, responseContent, "data_type: SomeDataType");
219 
220     return responseContent;
221   }
222 
223   private String assertXmlResponse(MockHttpServletResponse response,
224                                    int adaptorCount)
225                                    throws UnsupportedEncodingException {
226     String responseContent = response.getContentAsString();
227 
228     // assert response
229     assertEquals("Unexpected response status", 200, response.getStatus());
230     //Content it correct when executed via an HTTP client, but it doesn't seem
231     //to get set by the servlet
232     //assertEquals("Unexpected content type", "text/xml;charset=UTF-8",
233     //            response.getContentType());
234     assertOccurs("Response XML doesn't include correct adaptor_count", adaptorCount,
235             responseContent, "Adaptor>");
236     assertOccurs("Response XML doesn't include AdaptorClass", adaptorCount, responseContent,
237             "<AdaptorClass>org.apache.hadoop.chukwa.datacollection.adaptor.ChukwaTestAdaptor</AdaptorClass>");
238     assertOccurs("Response XML doesn't include dataType", adaptorCount, responseContent,
239             "dataType=\"SomeDataType\"");
240 
241     return responseContent;
242   }
243 
244   //  ** test utility methods **
245 
246   public void testPrintNvp() throws IOException {
247     AdaptorController.appendNvp(sb, "foo", "bar");
248     assertEquals("Unexpected NVP", "foo: bar\n", sb.toString());
249   }
250 
251   public void testPrintNvpIndented() throws IOException {
252     AdaptorController.appendNvp(sb, 4, "foo", "bar");
253     assertEquals("Unexpected NVP", "    foo: bar\n", sb.toString());
254   }
255 
256   public void testPrintNvpIndentedWithDash() throws IOException {
257     AdaptorController.appendNvp(sb, 4, "- foo", "bar");
258     assertEquals("Unexpected NVP", "  - foo: bar\n", sb.toString());
259   }
260 
261   public void testPrintNvpIndentedWithStringLiteral() throws IOException {
262     AdaptorController.appendNvp(sb, 4, "foo", "bar", true);
263     assertEquals("Unexpected NVP",
264             "    foo: |\n      bar\n", sb.toString());
265   }
266 
267   public void testPrintStartTag() throws IOException {
268     AdaptorController.appendStartTag(sb, "Foo");
269     assertEquals("Unexpected XML", "<Foo>", sb.toString());
270   }
271 
272   public void testPrintStartTagWithAttributes() throws IOException {
273     AdaptorController.appendStartTag(sb, "Foo", "a", "A", "b", "B <");
274     assertEquals("Unexpected XML",
275             "<Foo a=\"A\" b=\"B &lt;\">", sb.toString());
276   }
277 
278   public void testPrintElement() throws IOException {
279     AdaptorController.appendElement(sb, "Foo", "Bar");
280     assertEquals("Unexpected XML", "<Foo>Bar</Foo>", sb.toString());
281   }
282 
283   public void testPrintElementWithAttributes() throws IOException {
284     AdaptorController.appendElement(sb, "Foo", "Bar < -- />", "a", "A", "b", "B");
285     assertEquals("Unexpected XML",
286             "<Foo a=\"A\" b=\"B\">Bar &lt; -- /&gt;</Foo>", sb.toString());
287   }
288 
289   public void testPrintEndTag() throws IOException {
290     AdaptorController.appendEndTag(sb, "Foo");
291     assertEquals("Unexpected XML", "</Foo>", sb.toString());
292   }
293 }