| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.chukwa.database; |
| |
| import junit.framework.*; |
| import java.util.*; |
| import java.text.*; |
| import java.io.*; |
| import java.net.URL; |
| import java.sql.*; |
| import org.apache.commons.httpclient.*; |
| import org.apache.commons.httpclient.methods.*; |
| import org.apache.commons.httpclient.params.HttpMethodParams; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.json.simple.JSONArray; |
| import org.json.simple.JSONObject; |
| import org.json.simple.JSONValue; |
| import org.mortbay.jetty.Server; |
| import org.mortbay.xml.XmlConfiguration; |
| import org.apache.hadoop.chukwa.util.*; |
| |
| /* |
| * Testing the JSON output from the website with the database result. |
| * |
| */ |
| public class TestDatabaseWebJson extends TestCase { |
| protected HashMap testTables; |
| protected String data_url="http://localhost:8080/hicc/jsp/get_db_data.jsp"; |
| private Server server = null; |
| private Log log = LogFactory.getLog(TestDatabaseWebJson.class); |
| |
| /* |
| * setup list of tables to do testing. |
| * Add the table name and the table's primary keys. |
| */ |
| protected void setUp() { |
| testTables = new HashMap(); |
| |
| ArrayList<String> keys = new ArrayList<String>(); |
| keys.add("timestamp"); |
| keys.add("mount"); |
| testTables.put("cluster_disk", keys); |
| |
| keys = new ArrayList<String>(); |
| keys.add("timestamp"); |
| testTables.put("cluster_system_metrics", keys); |
| |
| keys = new ArrayList<String>(); |
| keys.add("timestamp"); |
| keys.add("host"); |
| keys.add("mount"); |
| testTables.put("disk", keys); |
| |
| keys = new ArrayList<String>(); |
| keys.add("job_id"); |
| testTables.put("mr_job", keys); |
| |
| keys = new ArrayList<String>(); |
| keys.add("task_id"); |
| testTables.put("mr_task", keys); |
| |
| keys = new ArrayList<String>(); |
| keys.add("timestamp"); |
| testTables.put("system_metrics", keys); |
| URL serverConf = TestDatabaseWebJson.class |
| .getResource("/WEB-INF/jetty.xml"); |
| server = new Server(); |
| XmlConfiguration configuration; |
| try { |
| configuration = new XmlConfiguration(serverConf); |
| configuration.configure(server); |
| server.start(); |
| server.setStopAtShutdown(true); |
| } catch (Exception e) { |
| log.error(ExceptionUtil.getStackTrace(e)); |
| } |
| } |
| |
| protected void tearDown() { |
| try { |
| server.stop(); |
| Thread.sleep(2000); |
| } catch (Exception e) { |
| log.error(ExceptionUtil.getStackTrace(e)); |
| } |
| } |
| |
| /* |
| * similar to PHP join function to join a string array to one single string. |
| * for example, if the token is "," and the strings array is ('a','b','c') |
| * the final result will be "a,b,c" |
| * |
| * @param token The separator which join the strings together |
| * @param strings list of strings which we want to merge together |
| * @return final string which merge together. |
| */ |
| protected static String join( String token, ArrayList<String> strings ) |
| { |
| StringBuffer sb = new StringBuffer(); |
| |
| for( int x = 0; x < ( strings.size() - 1 ); x++ ) { |
| sb.append( strings.get(x) ); |
| sb.append( token ); |
| } |
| sb.append( strings.get( strings.size() - 1 ) ); |
| |
| return( sb.toString() ); |
| } |
| |
| /* |
| * format the query string for the database testing. Select the |
| * primary key value from the json object. |
| * |
| * @param tableName The name of the database table to build the query on. |
| * @param jo JSON object which contain the primary key of the row which we |
| * want to test. |
| * @return the actual database query string for the row selection. |
| */ |
| protected String getDatabaseQuery(String tableName, JSONObject jo) { |
| ArrayList<String> keys = (ArrayList<String>)testTables.get(tableName); |
| ArrayList<String> criterias = new ArrayList<String>(); |
| Iterator i = keys.iterator(); |
| while (i.hasNext()) { |
| String key=(String)i.next(); |
| try { |
| String value=(String)jo.get(key); |
| if (key.compareToIgnoreCase("timestamp")==0) { |
| value=DatabaseWriter.formatTimeStamp(Long.parseLong(value)); |
| } |
| String c=key+"=\""+value+"\""; |
| criterias.add(c); |
| } catch (Exception e) { |
| System.out.println("Cannot get value for key: "+key); |
| } |
| } |
| String criteria=join(" and ", criterias); |
| |
| String query="select * from ["+tableName+"] where "+criteria; |
| return query; |
| } |
| |
| /* |
| * the function will do the actual table verification. If will first |
| * get the result from the website JSON object. Then it will compare the |
| * JSON object with the values in the database. |
| * |
| * @param table name of the table to be verified. |
| */ |
| protected void verifyTableData(String table) { |
| Calendar startCalendar = new GregorianCalendar(); |
| // startCalendar.add(Calendar.HOUR_OF_DAY,-1); |
| startCalendar.add(Calendar.MINUTE, -30); |
| long startTime=startCalendar.getTime().getTime(); |
| |
| Calendar endCalendar = new GregorianCalendar(); |
| // endCalendar.add(Calendar.HOUR_OF_DAY,1); |
| long endTime=endCalendar.getTime().getTime(); |
| |
| String url=data_url+"?table="+table+"&start="+startTime+"&end="+endTime; |
| System.out.println(url); |
| |
| HttpClient client = new HttpClient(); |
| GetMethod method = new GetMethod(url); |
| |
| |
| try { |
| |
| /* |
| * 1. get the json result for the specified table |
| */ |
| int statusCode = client.executeMethod(method); |
| if (statusCode != HttpStatus.SC_OK) { |
| System.out.println("Http Error: "+method.getStatusLine()); |
| } |
| BufferedReader reader = new BufferedReader(new InputStreamReader( method.getResponseBodyAsStream(), |
| method.getResponseCharSet())); |
| String json_str=""; |
| String str; |
| while ((str = reader.readLine()) != null) { |
| json_str+=str; |
| } |
| |
| /* |
| * 2. convert the json string to individual field and compare it |
| * with the database |
| */ |
| |
| String cluster = "demo"; |
| DatabaseWriter db = new DatabaseWriter(cluster); |
| |
| JSONArray json_array=(JSONArray)JSONValue.parse(json_str); |
| for (int i=0; i < json_array.size(); i++) { |
| JSONObject row_obj=(JSONObject) json_array.get(i); |
| |
| // get the database row |
| |
| String queryString=getDatabaseQuery(table, row_obj); |
| Macro m=new Macro(startTime, endTime, queryString); |
| ResultSet rs = db.query(m.toString()); |
| // move to the first record |
| rs.next(); |
| ResultSetMetaData md=rs.getMetaData(); |
| Iterator names=row_obj.keySet().iterator(); |
| while (names.hasNext()) { |
| String name=(String)names.next(); |
| String jsonValue=(String)row_obj.get(name); |
| String dbValue=rs.getString(name); |
| int dbCol=rs.findColumn(name); |
| int dbType=md.getColumnType(dbCol); |
| if (dbType==93) { |
| // timestamp |
| dbValue=Long.toString(rs.getTimestamp(name).getTime()); |
| } |
| // System.out.println("compare "+name+":"+dbType+":"+dbValue+":"+jsonValue); |
| assertEquals(dbValue, jsonValue); |
| } |
| } |
| |
| db.close(); |
| } catch (SQLException e) { |
| System.out.println("Exception: "+e.toString()+":"+e.getMessage()); |
| System.out.println("Exception: "+e.toString()+":"+e.getSQLState()); |
| System.out.println("Exception: "+e.toString()+":"+e.getErrorCode()); |
| fail("SQL Error:"+ExceptionUtil.getStackTrace(e)); |
| } catch (Exception eOther) { |
| System.out.println("Other Exception: "+eOther.toString()); |
| eOther.printStackTrace(); |
| fail("Error:"+ExceptionUtil.getStackTrace(eOther)); |
| } finally { |
| } |
| } |
| |
| /* |
| * Perform the actual testing. It will get the result from the web URL first. |
| * Then it will get the result from the database and compare it. |
| */ |
| public void testJsonResult() { |
| Iterator i=testTables.keySet().iterator(); |
| while (i.hasNext()) { |
| String tableName=(String)i.next(); |
| verifyTableData(tableName); |
| |
| } |
| } |
| } |