通过java模拟浏览器行为,对bugfree系统进行操作。譬如:通过bug id,查询bug的信息;查询产品族;查询满足特定条件的bug列表;批量更新bug的状态;上报bug到bugfree系统等。
package com.yunos.qa; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Map; public class BugfreeOperator { private static final String API_KEY = ""; private static final String bugfreeUrl = "http://bugfree-external.aliyun-inc.com/bugfree/api3.php"; private String sessionId; private SessionInfo sessionInfo; public BugfreeOperator() { } private SessionInfo getSessionInfo() { String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, "mode=getsid"); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return null; } SessionInfo sessionInfo = JsonParser.parseSessionInfo(jsonResult); System.out.println("sessionId: " + sessionInfo.getSessionId()); System.out.println("rand: " + sessionInfo.getRand()); return sessionInfo; } /** * * 认证码。 #加密算法: $auth = md5(md5($username.md5($password)).API_KEY.$rand) 其中$username为用户名,$password为该用户的明文密码,$rand为getsid方法获得的rand值。 * @param userName * @param password * @return */ public boolean login(String userName, String password) { sessionInfo = getSessionInfo(); if (sessionInfo == null) { return false; } String md5 = MD5.getMD5(password.getBytes()); System.out.println("md5: " + md5); md5 = userName + md5; md5 = MD5.getMD5(md5.getBytes()); md5 = md5 + API_KEY + sessionInfo.getRand(); String auth = MD5.getMD5(md5.getBytes()); Map<String, String> params = new HashMap<String, String>(); params.put("mode", "login"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("username", userName); params.put("auth", auth); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return false; } System.out.println("jsonResult: " + jsonResult); return JsonParser.parseLoginResult(jsonResult); } public void findProducts() { if (sessionInfo == null) { return; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "findproducts"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return; } System.out.println("[findProducts] jsonResult: " + jsonResult); return; } public void getBug(int id) { if (sessionInfo == null) { return; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "getbug"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("id", Integer.toString(id)); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return; } System.out.println("[getBug] jsonResult: " + jsonResult); return; } |
public void addBug(int product_id, BugInfo bugInfo, int productmodule_id) { if (sessionInfo == null) { return; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "addbug"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("product_id", Integer.toString(bugInfo.getProduct_id())); params.put("product_name", bugInfo.getProduct_name()); params.put("productmodule_id", Integer.toString(productmodule_id)); params.put("module_name", bugInfo.getModule_name()); params.put("title", bugInfo.getTitle()); params.put("priority", Integer.toString(bugInfo.getPriority())); params.put("severity", Integer.toString(bugInfo.getSeverity())); params.put("assign_to_name", bugInfo.getAssign_to_name()); params.put("BugType", bugInfo.getBugType()); //params.put("created_by", "1169"); //params.put("created_by_name", "haha"); params.put("bug_status", "Active"); DateFormat df=new SimpleDateFormat("yyyy-MM-dd"); Calendar c = Calendar.getInstance(); c.add(Calendar.DAY_OF_WEEK, 7); // 目前的時間加7天 //System.out.println(df.format(c.getTime())); //params.put("mail_to", "\u738b\u5947,\u4e5d\u91ce"); params.put("repeat_step", bugInfo.getRepeat_step()); params.put("Creater", "金永华"); params.put("Downgrade", "\u5426"); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return; } System.out.println("[addBug] jsonResult: " + jsonResult); return; } public void updateBugStatus(int id, String bug_status) { if (sessionInfo == null) { return; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "updatebug"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("id", Integer.toString(id)); params.put("bug_status", bug_status); params.put("severity", "4"); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return; } System.out.println("[updateBugStatus] jsonResult: " + jsonResult); } public Map<String, String> findModules(int product_id) { Map<String,String> moduleName2OwnerMap = new HashMap<String, String>(); if (sessionInfo == null) { return moduleName2OwnerMap; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "findmodules"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("product_id", Integer.toString(product_id)); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return moduleName2OwnerMap; } System.out.println("[findModules] jsonResult: " + jsonResult); JsonParser.parseModuleList(jsonResult, moduleName2OwnerMap); return moduleName2OwnerMap; } private static final String QUERY_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<query table=\"Bug\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://bugfree/query.xsd\">" + "<fields logic=\"OR\">" + "<field name=\"title\" operator=\"LIKE\" value=\"TITLE\"/>" + "</fields>" + "</query>"; public String queryByTitle(int product_id, String title) { String query = QUERY_TEMPLATE.replaceAll("TITLE", title); if (sessionInfo == null) { return ""; } Map<String, String> params = new HashMap<String, String>(); params.put("mode", "query"); params.put(sessionInfo.getSessionName(), sessionInfo.getSessionId()); params.put("product_id", Integer.toString(product_id)); params.put("query", query); String jsonResult = null; InputStream is = null; try { is = doPost(bugfreeUrl, params); jsonResult = getResult(is); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } if (jsonResult == null) { return ""; } return jsonResult; } public boolean hasNotClosed(String jsonResult) { if (jsonResult.equals("")) { return false; } if (jsonResult.contains("\"bug_status\":\"Active\"")) { return true; } return false; } public boolean hasClosed(String jsonResult) { if (jsonResult.equals("")) { return false; } if (jsonResult.contains("\"bug_status\":\"Closed\"")) { return true; } if (jsonResult.contains("\"bug_status\":\"Resolved\"")) { return true; } return false; } public boolean hasRejected(String jsonResult) { if (jsonResult.equals("")) { return false; } if (jsonResult.contains("\"solution\":\"Reject\"")) { return true; } if (jsonResult.contains("\"solution\":\"Won't Fix\"")) { return true; } // By Design if (jsonResult.contains("\"solution\":\"By Design\"")) { return true; } return false; } public InputStream doPost(String urlStr, Map<String, String> params) throws IOException { StringBuilder sb = new StringBuilder(); for(Map.Entry<String, String> param : params.entrySet()) { sb.append(param.getKey()).append("=").append(param.getValue()).append("&"); } int len = sb.length(); if (len > 0) { sb.deleteCharAt(len - 1); } String args = sb.toString(); //System.out.println("args: " + args); return doPost(urlStr, args); } public InputStream doPost(String urlStr, String args) throws IOException { URL url = null; try { url = new URL(urlStr); } catch (MalformedURLException e) { e.printStackTrace(); return null; } HttpURLConnection connection = (HttpURLConnection)url.openConnection(); //connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"); //String myCookie = "GerritAccount=aSecfaQr028r8-6yxggWFA1QQc0YQFz5"; if (sessionId != null) { System.out.println("sessionId: " + sessionId); connection.setRequestProperty("Cookie", sessionId); } //connection.setRequestProperty("Connection", "Keep-Alive"); /** * 然后把连接设为输出模式。URLConnection通常作为输入来使用,比如下载一个Web页。 * 通过把URLConnection设为输出,你可以把数据向你个Web页传送。下面是如何做: */ connection.setDoOutput(true); //connection.setRequestMethod("POST"); /** * 最后,为了得到OutputStream,简单起见,把它约束在Writer并且放入POST信息中,例如: ... */ OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); out.write(args); //向页面传递数据。post的关键所在! // remember to clean up out.flush(); out.close(); return connection.getInputStream(); } private static String getResult(InputStream is) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader( is)); String line = null; while ((line = br.readLine()) != null) { sb.append(line); } return sb.toString(); } } |
JsonParser用于解析从bugfree返回来的json信息:
package com.yunos.qa; import org.json.*; import java.util.Map; public class JsonParser { public static SessionInfo parseSessionInfo(String jsonResult) { System.out.println("sessionInfo: " + jsonResult); SessionInfo sessionInfo = new SessionInfo(); try { JSONObject jsonObj = new JSONObject(jsonResult); sessionInfo.setSessionName(jsonObj.getString("sessionname")); sessionInfo.setSessionId(jsonObj.getString("sessionid")); sessionInfo.setRand(jsonObj.getString("rand")); } catch(JSONException ex) { ex.printStackTrace(); } return sessionInfo; } public static boolean parseLoginResult(String jsonResult) { try { JSONObject jsonObj = new JSONObject(jsonResult); String status =jsonObj.getString("status"); return "success".equals(status); } catch(JSONException ex) { ex.printStackTrace(); } return false; } public static void parseModuleList(String jsonResult, Map<String,String> moduleName2OwnerMap) { try { JSONObject jsonObj = new JSONObject(jsonResult); JSONArray moduleList =jsonObj.getJSONArray("ModuleList"); int moduleCount = moduleList.length(); for(int i=0; i<moduleCount; i++) { JSONObject moduleObj = moduleList.getJSONObject(i); //System.out.println("module id:" + moduleObj.getString("id")); String moduleName = moduleObj.getString("name"); //System.out.println("module name:" + moduleName); //System.out.println("module product_id:" + moduleObj.getString("product_id")); //System.out.println("module grade:" + moduleObj.getString("grade")); //moduleObj.get //System.out.println("module parent_id:" + moduleObj.getString("parent_id")); //System.out.println("module full_path_name:" + moduleObj.getString("full_path_name")); //System.out.println("module display_order:" + moduleObj.getString("display_order")); //System.out.println("module owner_id:" + moduleObj.getString("owner_id")); String ownerName = moduleObj.getString("owner_name"); //System.out.println("module owner_name:" + ownerName); moduleName2OwnerMap.put(moduleName, ownerName); } } catch(JSONException ex) { ex.printStackTrace(); } } } |
SessionInfo用于会话信息:
package com.yunos.qa; public class SessionInfo { private String sessionName = ""; private String sessionId = ""; private String rand = ""; public String getSessionName() { return sessionName; } public void setSessionName(String sessionName) { this.sessionName = sessionName; } public String getSessionId() { return sessionId; } public void setSessionId(String sessionId) { this.sessionId = sessionId; } public String getRand() { return rand; } public void setRand(String rand) { this.rand = rand; } } |
BugInfo:javabean对象,用于映射bugfree中的bug:
package com.yunos.qa; public class BugInfo { private int product_id; // Integer 必须 产品id 1 private int productmodule_id; // Integer 模块id 1 private String product_name = ""; private String module_name = ""; private String title; //String 必须 Bug标题 1 private int severity = 4; //Integer 必须 严重程度 1,2,3,4 private int priority = 2; //Integer 优先级 1,2,3,4 private String repeat_step = ""; // String 重现步骤 private String assign_to_name = ""; //String 必须 指派给 系统管理员 private String BugType = ""; // String 必须 缺陷类型 //private String created_by = ""; //private String bug_status = ""; private String action_note = ""; //String 注释 private String mail_to = ""; //String 抄送给, 以','分割 系统管理员,admin@bugfree.org private int related_case = 0; //Integer 相关Case //attachment_file[] public BugInfo(int product_id, String title, int severity, String assign_to_name, String BugType) { this.product_id = product_id; if (title.length() > 102) { this.title = title.substring(0, 100); } else { this.title = title; } this.severity = severity; this.assign_to_name = assign_to_name; this.BugType = BugType; } public int getProduct_id() { return product_id; } public void setProduct_id(int product_id) { this.product_id = product_id; } public int getProductmodule_id() { return productmodule_id; } public void setProductmodule_id(int productmodule_id) { this.productmodule_id = productmodule_id; } public String getProduct_name() { return product_name; } public void setProduct_name(String product_name) { this.product_name = product_name; } public String getModule_name() { return module_name; } public void setModule_name(String module_name) { this.module_name = module_name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getSeverity() { return severity; } public void setSeverity(int severity) { this.severity = severity; } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } public String getRepeat_step() { return repeat_step; } public void setRepeat_step(String repeat_step) { this.repeat_step = repeat_step; } public String getAssign_to_name() { return assign_to_name; } public void setAssign_to_name(String assign_to_name) { this.assign_to_name = assign_to_name; } public String getBugType() { return BugType; } public void setBugType(String bugType) { BugType = bugType; } public String getAction_note() { return action_note; } public void setAction_note(String action_note) { this.action_note = action_note; } public String getMail_to() { return mail_to; } public void setMail_to(String mail_to) { this.mail_to = mail_to; } public int getRelated_case() { return related_case; } public void setRelated_case(int related_case) { this.related_case = related_case; } } |
其他:
bugfree在addbug时,对bug的title的内容是有校验的。我在用程序addbug时,遇到过一次addbug失败,报错信息如下:
{"status":"failed","code":7,"info":{"custom_field":"custom field [quot;_prio] is not valid field name"}}
title里边有一些特殊字符,会导致这个问题
最新内容请见作者的GitHub页:http://qaseven.github.io/