[jboss-svn-commits] JBL Code SVN: r35653 - in labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src: test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Oct 21 11:28:51 EDT 2010


Author: velias
Date: 2010-10-21 11:28:51 -0400 (Thu, 21 Oct 2010)
New Revision: 35653

Added:
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSourceTest.java
Modified:
   labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java
Log:
JIRAValueSource implemented with some unit tests, other tests must be done

Modified: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java	2010-10-21 15:24:51 UTC (rev 35652)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/main/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSource.java	2010-10-21 15:28:51 UTC (rev 35653)
@@ -1,18 +1,80 @@
 package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
 
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
 import org.jboss.community.sbs.plugin.reports.monthly.SystemConfigProvider;
 import org.jboss.community.sbs.plugin.reports.monthly.aggregator.AggregatorUtils;
 
+import au.com.bytecode.opencsv.CSVReader;
+
+import com.ibm.icu.text.SimpleDateFormat;
+
 /**
- * Data source to obtain report value for one project in JIRA.
+ * Data source to obtain report value for one repository/path pair in JIRA.
+ * <p>
+ * System Config parameters used by this value source:
+ * <ul>
+ * <li><code>org.jboss.community.sbs.plugin.reports.monthly.jira.url</code> - String - http/s url to JIRA server where
+ * is <a href="https://docspace.corp.redhat.com/docs/DOC-38712#Company_Contributions_Report"
+ * target="_blank">"Red Hat Contributors report" plugin</a>.
+ * <li><code>org.jboss.community.sbs.plugin.reports.monthly.jira.u</code> - String - username used to call JIRA
+ * <li><code>org.jboss.community.sbs.plugin.reports.monthly.jira.p</code> - String - password used to call JIRA
+ * <li><code>org.jboss.community.sbs.plugin.reports.monthly.jira.debug</code> - Boolean - if set to <code>true</code> no
+ * http/s calls to JIRA are performed, generator returns mock value only (all zero)
+ * </ul>
  * 
+ * TODO unit tests
+ * 
  * @author Vlastimil Elias (velias at redhat dot com)
  */
 public class JIRAValueSource extends ValueSourceBase<String> {
 
   /**
+   * TODO JIRA call parameter name for Maximal date.
+   */
+  protected static final String JIRA_PARAM_NAME_MAXDATE = "mad";
+
+  /**
+   * TODO JIRA call parameter name for Minimal date.
+   */
+  protected static final String JIRA_PARAM_NAME_MINDATE = "mid";
+
+  /**
+   * TODO Date parameters format used on FishEye call.
+   */
+  protected static final String JIRA_PARAM_DATE_FORMAT = "yyyy-M-d";
+
+  public static final String CONFIG_KEY_URL = "org.jboss.community.sbs.plugin.reports.monthly.jira.url";
+  public static final String CONFIG_KEY_USERNAME = "org.jboss.community.sbs.plugin.reports.monthly.jira.u";
+  public static final String CONFIG_KEY_PWD = "org.jboss.community.sbs.plugin.reports.monthly.jira.p";
+  public static final String CONFIG_KEY_DEBUG = "org.jboss.community.sbs.plugin.reports.monthly.jira.debug";
+
+  protected boolean debug = false;
+
+  protected HttpClient client;
+
+  protected boolean doAuthentication = false;
+
+  protected Map<String, String[]> cache = null;
+
+  protected Exception cacheE = null;
+
+  /**
    * Constructor.
    * 
    * @param sysConfig System configuration provider to be used
@@ -21,12 +83,145 @@
    */
   public JIRAValueSource(SystemConfigProvider sysConfig, Date dateFrom, Date dateTo) {
     super(sysConfig, dateFrom, dateTo);
+    if (sysConfig != null && !sysConfig.getBooleanProperty(CONFIG_KEY_DEBUG)) {
+      debug = false;
+    } else {
+      debug = true;
+    }
+    if (!debug) {
+      initHttpClient();
+    }
   }
 
+  /**
+   * Init HTTP client.
+   */
+  protected void initHttpClient() {
+
+    String url = StringUtils.trimToNull(sysConfig.getStringProperty(CONFIG_KEY_URL));
+    if (url == null) {
+      throw new IllegalArgumentException("JIRA url not defined in system config property: " + CONFIG_KEY_URL);
+    }
+
+    client = new HttpClient();
+    String un = StringUtils.trimToNull(this.sysConfig.getStringProperty(CONFIG_KEY_USERNAME));
+    String pwd = StringUtils.trimToEmpty(this.sysConfig.getStringProperty(CONFIG_KEY_PWD));
+    if (un != null) {
+      client.getState().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
+          new UsernamePasswordCredentials(un, pwd));
+      doAuthentication = true;
+    }
+  }
+
   @Override
-  public String[] getValues(String projectKey) {
-    // TODO implement me
-    return AggregatorUtils.createFilledArray(4, "0");
+  public String[] getValues(String projectKey) throws Exception {
+
+    if (projectKey == null)
+      throw new IllegalArgumentException("JIRA project key can't be null");
+
+    if (debug) {
+      return AggregatorUtils.createFilledArray(4, "0");
+    }
+
+    if (cache == null) {
+      // preven many hits to JIRA in case of problems
+      if (cacheE != null) {
+        throw cacheE;
+      }
+      try {
+        cache = loadData();
+      } catch (Exception e) {
+        cacheE = e;
+        throw e;
+      }
+    }
+
+    String[] ret = cache.get(projectKey);
+    if (ret == null) {
+      ret = AggregatorUtils.createFilledArray(4, "0");
+    }
+
+    return ret;
   }
 
+  protected Map<String, String[]> loadData() throws IOException {
+    HttpMethod method = new GetMethod(StringUtils.trimToNull(sysConfig.getStringProperty(CONFIG_KEY_URL)));
+    method.setDoAuthentication(doAuthentication);
+    method.setFollowRedirects(true);
+    method.setQueryString(prepareParams());
+    try {
+
+      int statusCode = client.executeMethod(method);
+
+      if (statusCode != HttpStatus.SC_OK) {
+        throw new IOException("JIRA HTTP call failed with http code: " + method.getStatusCode() + " and message: "
+            + method.getStatusLine());
+      }
+
+      return processResponse(method.getResponseBody());
+
+    } finally {
+      method.releaseConnection();
+    }
+  }
+
+  /**
+   * Prepare HTTP parameters to call JIRA server.
+   * 
+   * @return prepared HTTP parameters
+   */
+  protected NameValuePair[] prepareParams() {
+    List<NameValuePair> params = new ArrayList<NameValuePair>();
+    SimpleDateFormat sdf = new SimpleDateFormat(JIRA_PARAM_DATE_FORMAT);
+    if (dateFrom != null) {
+      params.add(new NameValuePair(JIRA_PARAM_NAME_MINDATE, sdf.format(dateFrom)));
+    }
+    if (dateTo != null) {
+      params.add(new NameValuePair(JIRA_PARAM_NAME_MAXDATE, sdf.format(dateTo)));
+    }
+    return params.toArray(new NameValuePair[] {});
+  }
+
+  /**
+   * Proces response from JIRA server.
+   * 
+   * @param responseBody to process
+   * @return data loaded from JIRA
+   * @throws IOException
+   */
+  protected Map<String, String[]> processResponse(byte[] responseBody) throws IOException {
+    if (responseBody == null || responseBody.length == 0) {
+      throw new IOException("JIRA HTTP call failed: empty response");
+    }
+
+    String response = (new String(responseBody)).trim();
+
+    int idx = response.indexOf("id=\"jira_cont_rep_csv\"");
+    int startIdx = response.indexOf(">", idx) + 1;
+    int endIdx = response.indexOf("<", startIdx);
+
+    if (startIdx == -1 || endIdx == -1 || startIdx > endIdx) {
+      throw new IOException("JIRA HTTP call failed: Bad response, no csv file part found in returned data.");
+    }
+
+    String csvcontent = response.substring(startIdx, endIdx).trim();
+
+    CSVReader reader = new CSVReader(new StringReader(csvcontent), ',');
+
+    Map<String, String[]> ret = new HashMap<String, String[]>();
+
+    String[] row = null;
+
+    boolean first = true;
+    while ((row = reader.readNext()) != null) {
+      // skip header
+      if (first) {
+        first = false;
+      } else {
+        ret.put(row[0], (String[]) ArrayUtils.subarray(row, 2, 6));
+      }
+    }
+
+    return ret;
+  }
 }

Added: labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSourceTest.java
===================================================================
--- labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSourceTest.java	                        (rev 0)
+++ labs/jbosslabs/labs-3.0-build/integration/sbs/reports/trunk/src/test/java/org/jboss/community/sbs/plugin/reports/monthly/valuesource/JIRAValueSourceTest.java	2010-10-21 15:28:51 UTC (rev 35653)
@@ -0,0 +1,349 @@
+package org.jboss.community.sbs.plugin.reports.monthly.valuesource;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.jboss.community.sbs.plugin.reports.monthly.MapBasedSystemConfigProvider;
+import org.jboss.community.sbs.plugin.reports.monthly.SystemConfigProvider;
+import org.jboss.community.sbs.plugin.reports.monthly.aggregator.AggregatorUtils;
+import org.jboss.community.sbs.plugin.reports.monthly.config.FishEyeRepositoryConfig;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.ibm.icu.text.SimpleDateFormat;
+
+/**
+ * Unit test for {@link FISHEYEValueSource}.
+ * 
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class JIRAValueSourceTest {
+
+  protected static final int ROW_SIZE = 4;
+
+  @Test
+  public void getValues_caches() throws Exception {
+
+    MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_DEBUG, "false");
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_URL, "http://test.jboss.org");
+    JIRAValueSourceMock tested = new JIRAValueSourceMock(config, false);
+
+    String[] ret = tested.getValues("ORG");
+    Assert.assertEquals(1, tested.checkCallCount());
+    Assert.assertEquals(ROW_SIZE, ret.length);
+    Assert.assertEquals("1", ret[0]);
+
+    ret = tested.getValues("ORG_UNKNOWN");
+    // cache used
+    Assert.assertEquals(0, tested.checkCallCount());
+    Assert.assertEquals(ROW_SIZE, ret.length);
+    // unknown project return 0
+    Assert.assertEquals("0", ret[0]);
+
+    ret = tested.getValues("JBAS");
+    // cache used
+    Assert.assertEquals(0, tested.checkCallCount());
+    Assert.assertEquals(ROW_SIZE, ret.length);
+    Assert.assertEquals("10", ret[0]);
+  }
+
+  @Test
+  public void getValues_cacheException() throws Exception {
+
+    MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_DEBUG, "false");
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_URL, "http://test.jboss.org");
+    JIRAValueSourceMock tested = new JIRAValueSourceMock(config, true);
+
+    try {
+      tested.getValues("ORG");
+      Assert.fail("IOException must be thrown");
+    } catch (IOException e) {
+      // OK
+    }
+    Assert.assertEquals(1, tested.checkCallCount());
+
+    // cache used
+    try {
+      tested.getValues("ORG44");
+      Assert.fail("IOException must be thrown");
+    } catch (IOException e) {
+      // OK
+    }
+    Assert.assertEquals(0, tested.checkCallCount());
+
+    try {
+      tested.getValues("ORG22");
+      Assert.fail("IOException must be thrown");
+    } catch (IOException e) {
+      // OK
+    }
+    Assert.assertEquals(0, tested.checkCallCount());
+
+  }
+
+  @Test
+  public void processResponse() throws IOException {
+    // TODO unit test
+
+    FISHEYEValueSource tested = new FISHEYEValueSource(null, null, null);
+
+    String[] ret = null;
+    try {
+      ret = tested.processResponse(null);
+      Assert.fail("No exception thrown");
+    } catch (IOException e) {
+      // OK
+    }
+
+    try {
+      ret = tested.processResponse("".getBytes());
+      Assert.fail("No exception thrown");
+    } catch (IOException e) {
+      // OK
+    }
+
+    try {
+      ret = tested.processResponse("fault:Erro xxxx".getBytes());
+      Assert.fail("No exception thrown");
+    } catch (IOException e) {
+      // OK
+    }
+
+    try {
+      ret = tested.processResponse("ok:1".getBytes());
+      Assert.fail("No exception thrown");
+    } catch (IOException e) {
+      // OK
+    }
+
+    try {
+      ret = tested.processResponse("nook:1:10".getBytes());
+      Assert.fail("No exception thrown");
+    } catch (IOException e) {
+      // OK
+    }
+
+    ret = tested.processResponse("ok:1:10".getBytes());
+    Assert.assertEquals("1", ret[0]);
+    Assert.assertEquals("10", ret[1]);
+  }
+
+  @Test
+  public void prepareParams() throws Exception {
+    JIRAValueSource tested = new JIRAValueSource(null, null, null);
+    SimpleDateFormat sdf = new SimpleDateFormat(JIRAValueSource.JIRA_PARAM_DATE_FORMAT);
+
+    // no params
+    NameValuePair[] val = tested.prepareParams();
+
+    Assert.assertNull(getParameter(val, JIRAValueSource.JIRA_PARAM_NAME_MINDATE));
+    Assert.assertNull(getParameter(val, JIRAValueSource.JIRA_PARAM_NAME_MAXDATE));
+
+    // all params set
+    tested.dateFrom = sdf.parse("2010-10-01");
+    tested.dateTo = sdf.parse("2010-10-31");
+    val = tested.prepareParams();
+
+    Assert.assertEquals("2010-10-1", getParameter(val, JIRAValueSource.JIRA_PARAM_NAME_MINDATE));
+    Assert.assertEquals("2010-10-31", getParameter(val, JIRAValueSource.JIRA_PARAM_NAME_MAXDATE));
+  }
+
+  protected String getParameter(NameValuePair[] val, String name) {
+    for (NameValuePair p : val) {
+      if (p.getName().equals(name)) {
+        return p.getValue();
+      }
+    }
+    return null;
+  }
+
+  @Test
+  public void initHttpClient() {
+    MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_DEBUG, "false");
+
+    JIRAValueSource tested = null;
+    try {
+      tested = new JIRAValueSource(config, null, null);
+      Assert.fail("IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException e) {
+      // OK
+    }
+
+    // no authentication
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_URL, "http://test.jboss.org");
+    tested = new JIRAValueSource(config, null, null);
+    Assert.assertNotNull(tested.client);
+    Assert.assertFalse(tested.debug);
+    Assert.assertFalse(tested.doAuthentication);
+
+    // with authentication
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_USERNAME, "un");
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_PWD, "pw");
+    tested = new JIRAValueSource(config, null, null);
+    Assert.assertNotNull(tested.client);
+    Assert.assertFalse(tested.debug);
+    Assert.assertTrue(tested.doAuthentication);
+    UsernamePasswordCredentials cr = (UsernamePasswordCredentials) tested.client.getState().getCredentials(
+        new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM));
+    Assert.assertEquals("un", cr.getUserName());
+    Assert.assertEquals("pw", cr.getPassword());
+
+  }
+
+  @Test
+  public void getValues_DEBUG() throws Exception {
+
+    // test debug mode of provider
+    MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+    config.addConfigProperty(JIRAValueSource.CONFIG_KEY_DEBUG, "true");
+
+    JIRAValueSource tested = new JIRAValueSource(config, null, null);
+
+    String[] val = null;
+    try {
+      val = tested.getValues(null);
+      Assert.fail();
+    } catch (IllegalArgumentException e) {
+      // OK
+    }
+
+    val = tested.getValues("PROJ");
+    Assert.assertEquals(ROW_SIZE, val.length);
+    Assert.assertEquals("0", val[0]);
+    Assert.assertEquals("0", val[1]);
+    Assert.assertEquals("0", val[2]);
+    Assert.assertEquals("0", val[3]);
+  }
+
+  @Test
+  public void loadData_REMOTE_NOAUTH() throws Exception {
+    // TODO unit test
+    HttpFISHEYEMockServer server = new HttpFISHEYEMockServer();
+    try {
+
+      MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_DEBUG, "false");
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_URL, "http://localhost:" + HttpFISHEYEMockServer.PORT);
+
+      FISHEYEValueSource tested = new FISHEYEValueSource(config, null, null);
+
+      // all ok
+      server.connect();
+      FishEyeRepositoryConfig id = new FishEyeRepositoryConfig("REPO");
+      String[] val = tested.getValues(id);
+      server.disconnect();
+      Assert.assertEquals(2, val.length);
+      Assert.assertEquals("10", val[0]);
+      Assert.assertEquals("100", val[1]);
+      Assert.assertEquals("REPO", server.p_repo);
+      Assert.assertNull(server.p_path);
+      Assert.assertNull(server.p_mindate);
+      Assert.assertNull(server.p_maxdate);
+      Assert.assertNull(server.h_auth);
+
+      // data error from server
+      try {
+        server.dataok = false;
+        server.connect();
+        val = tested.getValues(id);
+        Assert.fail();
+      } catch (IOException e) {
+        // ok
+      } finally {
+        server.disconnect();
+      }
+
+      try {
+        server.dataok = true;
+        server.statusok = false;
+        server.connect();
+        val = tested.getValues(id);
+        Assert.fail();
+      } catch (IOException e) {
+        // ok
+      } finally {
+        server.disconnect();
+      }
+
+    } finally {
+      server.disconnect();
+    }
+  }
+
+  @Test
+  public void loadData_REMOTE_AUTH() throws Exception {
+    // TODO unit test
+    HttpFISHEYEMockServer server = new HttpFISHEYEMockServer();
+    server.doauth = true;
+    try {
+
+      MapBasedSystemConfigProvider config = new MapBasedSystemConfigProvider();
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_DEBUG, "false");
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_URL, "http://localhost:" + HttpFISHEYEMockServer.PORT);
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_USERNAME, "user");
+      config.addConfigProperty(FISHEYEValueSource.CONFIG_KEY_PWD, "pwd");
+
+      FISHEYEValueSource tested = new FISHEYEValueSource(config, null, null);
+
+      // all ok
+      server.connect();
+      FishEyeRepositoryConfig id = new FishEyeRepositoryConfig("REPO");
+      id.setPath("/path");
+      String[] val = tested.getValues(id);
+      server.disconnect();
+      Assert.assertEquals(2, val.length);
+      Assert.assertEquals("10", val[0]);
+      Assert.assertEquals("100", val[1]);
+      Assert.assertEquals("REPO", server.p_repo);
+      Assert.assertEquals("/path", server.p_path);
+      Assert.assertNull(server.p_mindate);
+      Assert.assertNull(server.p_maxdate);
+      Assert.assertNotNull(server.h_auth);
+
+    } finally {
+      server.disconnect();
+    }
+
+  }
+
+  protected static class JIRAValueSourceMock extends JIRAValueSource {
+
+    private boolean exception = false;
+
+    private int callcount = 0;
+
+    public int checkCallCount() {
+      int ret = callcount;
+      callcount = 0;
+      return ret;
+    }
+
+    public JIRAValueSourceMock(SystemConfigProvider sysConfig, boolean exception) {
+      super(sysConfig, null, null);
+      this.exception = exception;
+    }
+
+    @Override
+    protected Map<String, String[]> loadData() throws IOException {
+
+      callcount++;
+      if (exception) {
+        throw new IOException();
+      }
+
+      Map<String, String[]> ret = new HashMap<String, String[]>();
+      ret.put("ORG", AggregatorUtils.createFilledArray(ROW_SIZE, "1"));
+      ret.put("JBAS", AggregatorUtils.createFilledArray(ROW_SIZE, "10"));
+      return ret;
+    }
+
+  }
+
+}



More information about the jboss-svn-commits mailing list