Jump to: navigation, search

Difference between revisions of "OSEE/Developer Guidelines"

(Code Quality Configuration)
(Code Quality Configuration)
(42 intermediate revisions by 6 users not shown)
Line 1: Line 1:
__NOTOC__
+
== Before Committing Code ==
= Setup =
+
 
 +
# Synchronize and Update
 +
# Run Code Quality Checks
 +
# Ensure all the tests are green. (Tests projects can be identified by their '*.test' suffix. All tests have to be executed as plug-in unit tests.)
 +
# Ensure the reference documentation is up to date (i.e. reflects your changes) (Documentation is maintained in project 'via the OSEE wiki').
  
 
== Code Quality Tools ==
 
== Code Quality Tools ==
Line 8: Line 12:
 
* [http://findbugs.sourceforge.net/ Find Bugs] - Used to perform static analysis on java code - [http://findbugs.cs.umd.edu/eclipse Find Bugs Update Site]
 
* [http://findbugs.sourceforge.net/ Find Bugs] - Used to perform static analysis on java code - [http://findbugs.cs.umd.edu/eclipse Find Bugs Update Site]
 
* [http://pmd.sourceforge.net/ PMD] - Additional static analysis and code duplication checks - [http://pmd.sourceforge.net/eclipse PMD Update Site]
 
* [http://pmd.sourceforge.net/ PMD] - Additional static analysis and code duplication checks - [http://pmd.sourceforge.net/eclipse PMD Update Site]
* [http://eclipse-cs.sf.net Check Style] - Code Style Checks - [http://sourceforge.net/projects/eclipse-cs/files/Eclipse%20Checkstyle%20Plug-in/v5.0.0final/net.sf.eclipsecs-5.0.0.200906281855-final-updatesite.zip/download Check Style Archived Update Site] '''* This is an archived update site'''
+
* [http://eclipse-cs.sf.net Check Style] - Code Style Checks - [http://eclipse-cs.sf.net/update/ Check Style Update Site]
* [http://www.eclemma.org/index.html Eclipse Emma] - Emma Coverage Tool Plugin For Eclipse - see below for installation instructions
+
* [http://www.eclemma.org/index.html Eclipse Emma] - Emma Coverage Tool Plugin For Eclipse - [http://update.eclemma.org/ Emma update site]
 
+
Installation for Find Bugs, PMD, Emma, and Check Style:
Installation for Find Bugs, PMD, and Check Style:
+
  
 
# Launch Eclipse and go to '''Help->Software Updates->Available Software'''
 
# Launch Eclipse and go to '''Help->Software Updates->Available Software'''
Line 18: Line 21:
 
# Click the '''Install''' button
 
# Click the '''Install''' button
 
# Once installation completes, restart eclipse
 
# Once installation completes, restart eclipse
 
Installation for Eclipse EMMA:
 
 
# Download zip file from the following link [http://sourceforge.net/projects/eclemma/files/1%20EclEmma%20Releases/1.4.1/eclemma-1.4.1.zip/download Eclipse Emma Zip File]
 
# Unzip downloaded file into your '''dropins''' folder
 
# Restart Eclipse
 
  
 
==Code Quality Configuration==
 
==Code Quality Configuration==
  
===Import OSEE Team Preferences===
+
===Import OSEE Team Preferences ===
  
# Right-click on the following link [http://dev.eclipse.org/svnroot/technology/org.eclipse.osee/trunk/org.eclipse.osee.support.config/osee_team_3.4.epf '''OSEE Team Preferences''']
+
# Right-click on the following link [http://git.eclipse.org/c/osee/org.eclipse.osee.git/plain/plugins/org.eclipse.osee.support.config/osee_team_preferences.epf '''OSEE Team Preferences''']
 
# Select '''Save Link As'''
 
# Select '''Save Link As'''
# Enter '''osee_team_3.4.epf''' and click '''Save'''
+
# Enter '''osee_team_preferences.epf''' and click '''Save'''
 
# Launch Eclipse
 
# Launch Eclipse
# Select '''File->Import->General->Preferences'''
+
# Select '''File->Import'''
# Click on '''Browse''', navigate to the location where you saved '''osee_team_3.4.epf'''
+
# Open the '''General''' folder
# Select to '''Import all'''
+
# Select '''Preferences'''
# Click '''Finish'''
+
# Click on the '''Browse...''' button, navigate to the location where you saved '''osee_team_preferences.epf'''
 +
# Select '''Import all'''
 +
# Click '''Finish''' to import settings
  
 
===Check Style Configuration===
 
===Check Style Configuration===
Line 45: Line 44:
 
# Select '''Remote Configuration''' under the '''Type''' drop down
 
# Select '''Remote Configuration''' under the '''Type''' drop down
 
# Set name to '''OSEE Checks (Eclipse)'''
 
# Set name to '''OSEE Checks (Eclipse)'''
# Copy the following link into the '''Location''' entry [http://dev.eclipse.org/svnroot/technology/org.eclipse.osee/trunk/org.eclipse.osee.support.config/codeStyle/osee_check_style.xml '''OSEE Checks (Eclipse)''']
+
# Copy the following link into the '''Location''' entry [http://git.eclipse.org/c/osee/org.eclipse.osee.git/plain/plugins/org.eclipse.osee.support.config/codeStyle/osee_check_style.xml '''OSEE Checks (Eclipse)''']
 
# Set the '''Cache configuration file''' checkbox to true
 
# Set the '''Cache configuration file''' checkbox to true
# Click ''OK'''
+
# Click '''OK'''
 
# Select the '''OSEE Checks (Eclipse)''' configuration and click on '''Set as Default'''
 
# Select the '''OSEE Checks (Eclipse)''' configuration and click on '''Set as Default'''
 
# Click '''OK''' to accept settings
 
# Click '''OK''' to accept settings
Line 60: Line 59:
 
===PMD Configuration===
 
===PMD Configuration===
  
# Right-click on the following link [http://dev.eclipse.org/svnroot/technology/org.eclipse.osee/trunk/org.eclipse.osee.support.config/codeStyle/osee_pmd_rule_set.xml '''OSEE PMD Rule Set''']
+
# Right-click on the following link [http://git.eclipse.org/c/osee/org.eclipse.osee.git/plain/plugins/org.eclipse.osee.support.config/codeStyle/osee_pmd_rule_set.xml '''OSEE PMD Rule Set''']
 
# Select '''Save Link As'''
 
# Select '''Save Link As'''
 
# Enter '''osee_pmd_rule_set.xml''' and click '''Save'''
 
# Enter '''osee_pmd_rule_set.xml''' and click '''Save'''
Line 72: Line 71:
  
 
== Monitor OSEE Bugs using Mylyn ==
 
== Monitor OSEE Bugs using Mylyn ==
 +
See [[Integrating OSEE and Bugzilla]].
  
[[Integrating OSEE and Bugzilla]]
+
== Coding Standards ==
  
= Before Committing Code =
+
=== Utility Classes ===
  
# Synchronize and Update
+
In order to optimize reuse of code, OSEE developers have adopted a set of standards.
# Run Code Quality Checks
+
 
# Ensure all the tests are green. (Tests projects can be identified by their '*.test' suffix. All tests have to be executed as plug-in unit tests.)
+
Utility classes should:
# Ensure the reference documentation is up to date (i.e. reflects your changes) (Documentation is maintained in project 'via the OSEE wiki').
+
# Be named xxxUtil.  This allows for each searching and location by looking for *Util.  This excludes stand-alone utility classes like HashCollection or CountingMap.
 +
# As much as possible, be located in a package postfix'd with .util. eg. org.eclipse.osee.ats.util
 +
# Should contain static methods
 +
 
 +
==== Cleanup of existing utility methods ====
 +
 
 +
The following needs to be done:
 +
# Create set of common utility class names
 +
# Move utilities to their respective places
 +
# Either deprecate or replace uses of old locations
 +
 
 +
=== Comments ===
 +
Most comments offer more clutter than information, especially <tt>non-Javadoc</tt> comments which can be removed using the following regular expression <code>\R&#91; \t&#93;*/\*\s+&#91;\* &#93;*\(non-Javadoc\)&#91;^/&#93;+/</code>.
 +
 
 +
=== Regular Expression Find/Replace application of standards ===
 +
* <code>([^ ]+) != null && !(\1).equals\(""\)</code> replace with <code>Strings.isValid($1)</code>
 +
* <code>([^ ]+) == null \|\| (\1).equals\(""\)</code> replace with <code>!Strings.isValid($1)</code>
 +
 
 +
== OSEE Master Test Suite ==
 +
 
 +
OSEE uses JUnit 4 for its test suites.  Some links to get started:
 +
* [http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/ Jnit4 in 60 seconds]
 +
* [http://stackoverflow.com/questions/264680/best-way-to-automagically-migrate-tests-from-junit-3-to-junit-4/677356 Upgrading to JUnit4]
 +
 
 +
=== Use Cases ===
 +
 
 +
Requirements of the OSEE test suite:
 +
 
 +
# Single button press to run all tests
 +
# Minimal number of launch configurations to maintain
 +
# Ability for any user, internal or external, to easily run a suite of tests before commit
 +
# Continuous integration (checkout, build, test, report)
 +
# Use JUnit framework for all testing
 +
# Enable health checks against production database to be part of test suite
 +
# New test cases can be added easily
 +
 
 +
=== Running the OSEE Test Suite ===
 +
 
 +
The OSEE test suite uses the <tt>org.eclipse.osee.ats.config.demo</tt> plugin to initialize a demo database, populate it with demo data and run the majority of the OSEE tests against this common data set.
 +
 
 +
These tests are contributed to the MasterTestSuite groups using Eclipse's extension point framework. Any Test Suite can implement IOseeTest and extend the OseeTest extension point to be contributed to the appropriate test suite(s).
 +
 
 +
==== Steps to test ====
 +
# Checkout org.eclipse.osee.ats.config.demo
 +
# Checkout org.eclipse.osee.support.test
 +
# Run the following tests in order and resolve any errors:
 +
## Run the Demo database tests:
 +
### Run the '''OSEE Demo Application Server''' launch config
 +
### Run the '''MasterTestSuite_DemoDbInit''' launch config. This initializes the postgres database for demo populate and tests
 +
### Run the '''MasterTestSuite_DemoDbPopulate''' launch config.  This loads the database with branches, actions and sets conditions for populate tests.
 +
### Run the '''MasterTestSuite_DemoDbTests''' launch config.  This runs tests against the DemoDb Populated database.
 +
### Stop the '''OSEE Demo Application Server''' if still running
 +
## Run the Production TestDb tests:
 +
### Run the '''OSEE Application Server''' launch config.
 +
### Run the '''MasterTestSuite_TestDbInit''' launch config.  This initializes the postgres database for production testdb tests
 +
### Run the '''MasterTestSuite_TestDbTests''' launch config. - This runs production specific tests using a TestDb.
 +
## Run the Production tests and health checks against the current production release
 +
### Run the '''MasterTestSuite_ProductionTests''' launch config.  This runs tests and health checks against the current production released database.
 +
 
 +
===Common test utility plugin===
 +
 
 +
The plugin org.eclipse.osee.support.test.util is in support of our testing framework.  It has a number of common enums and a TestUtil class that should be used by any junit tests.  The intent is to keep this plugin lightweight and without many dependencies cause all the testing fragments "should" include it.  In addition, it should not be included by any production plugins, only test fragments.
 +
 
 +
=== Adding new Tests to MasterTestSuite ===
 +
 
 +
=== To create test fragment off plugin to be tested ===
 +
All OSEE JUnit tests should live in a fragment of the plugin to be tested.
 +
# Select plugin to be tested
 +
# Right-click -> New Project -> Plugin Project -> Plugin Fragment
 +
# Enter plugin to be tested as Host plugin
 +
# Complete wizard
 +
# In plugin to be tested (eg org.eclipse.osee.ats)
 +
## Add "Eclipse-ExtensibleAPI: true" to MANIFEST.MF of plugin to be tested.  This allows test suites to see tests in this plugin
 +
# In new fragment (eg org.eclipse.osee.ats.test)
 +
## Add org.junit4 (make sure junit4, not junit) to dependencies
 +
## Add the common test utility plugin org.eclipse.osee.support.test.util plugin to dependencies
 +
## Export packages containing TestCases and TestSuites
 +
# In MasterTestSuite plugin (eg org.eclipse.osee.support.test)
 +
## Add dependency on plugin to be tested (ge org.eclipse.osee.ats)
 +
## Add test cases and suites from fragment to appropriate MasterTestSuite java Test Suites
 +
 
 +
=== To add a new JUnit TestCase ===
 +
# Write the TestCase to run against a database populated with DemoDbInit and DemoDbPopulate
 +
# Add the TestCase to an existing MasterTestSuite_DemoDbTests test suite
 +
 
 +
=== Things to consider ===
 +
# Your tests must clean-up after themselves to ensure that the entire test suite can be run.
 +
# Do not assume order of execution except within your own Test Suite
 +
 
 +
=== Master Test Suite - Frequently Asked Questions ===
 +
 
 +
==== What do I need for every test case? ====
 +
* import static org.junit.Assert.*;
 +
* In setup method (@Before), always assert that you are on correct database by adding one of these
 +
<source lang=sql>
 +
assertTrue("Should be run on production datbase.", TestUtil.isProductionDb());
 +
assertTrue("Should be run on test datbase.", TestUtil.isTestDb());
 +
assertTrue("Should be run on demo datbase.", TestUtil.isDemoDb());
 +
 
 +
</source>
 +
* In setup method (@Before), always assert that you have correct app server running *
 +
<source lang=sql>
 +
assertTrue("Demo Application Server must be running.",
 +
  ClientSessionManager.getAuthenticationProtocols().contains("demo"));
 +
assertTrue("Client must authenticate using demo protocol",
 +
  ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
 +
 
 +
assertFalse("Application Server must be running.",
 +
  ClientSessionManager.getAuthenticationProtocols().contains("demo"));
 +
assertFalse("Client can't authenticate using demo protocol",
 +
  ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
 +
}
 +
</source>
 +
 
 +
==== Why do I get an exception on synchronized-lock when I launch the tests ====
 +
 
 +
The launch configuration does not have all plugins necessary to run. 
 +
# Open Debug Configurations for that launch item
 +
# Go to plugins tab and select "Validate Plugins".  This will show if any plugins are missing from selected items. 
 +
# Select "Add Required Plugins" to add them. 
 +
# Re-launch.
 +
 
 +
==== Why do I get exceptions that cycle was detected when I add things to the org.eclipse.osee.test.util plugin ====
 +
 
 +
This plugin is meant to be extremely light-weight and only provide simple statics and methods to all the test plugins.  Because it has to be included in all test fragments from jdk.core all the way up to framework.ui (skynet.ui), it can not depend on any of the higher level plugins or cycles will occur. Remove these dependencies and cycles will be fixed.
 +
 
 +
==== How do I timeout a test? ====
 +
 
 +
Define a timeout period in miliseconds with “timeout” parameter. The test fails when the timeout period exceeds.
 +
view
 +
<source lang="java">
 +
@Test(timeout = 1000) 
 +
public void infinity() { 
 +
    while (true); 
 +
 +
</source>
 +
 
 +
==== How do I test exception handling ====
 +
 
 +
Exception Handling
 +
Use “expected” paramater with @Test annotation for test cases that expect exception. Write the class name of the exception that will be thrown.
 +
view plainprint?
 +
<source lang="java">
 +
@Test(expected = ArithmeticException.class) 
 +
public void divisionWithException() { 
 +
  // divide by zero 
 +
  simpleMath.divide(1, 0); 
 +
}
 +
</source>
 +
 
 +
=== To add a new JUnit TestSuite ===
 +
# Create a fragment for the plugin (see above)
 +
# Create new JUnit TestCases as above
 +
# Create a new JUnit TestSuite
 +
# Add new TestSuite to one of the MasterTestSuite java test suites
 +
 
 +
=== Common test cases ===
 +
<source lang="java">
 +
/*
 +
    COMPANY DISTRIBUTION STATEMENT
 +
*/
 +
 +
package com.company.component.testcase;
 +
 
 +
import
 +
...
 +
import org.junit.After;
 +
import org.junit.AfterClass;
 +
import org.junit.Assert;
 +
import org.junit.Before;
 +
import org.junit.BeforeClass;
 +
import org.junit.Test;
 +
 
 +
/**
 +
* @link <link_to_class_under_test>
 +
* @author <you>
 +
*/
 +
public final class MySuperbTest {
 +
 
 +
  private static SevereLoggingMonitor monitorLog = null;
 +
  private static Artifact myRootArtifact = null;
 +
 
 +
  @Test
 +
  public void importSimpleArtifacts() throws Exception {
 +
      Assert.assertTrue("Some message...", conditionToBeTrue);
 +
  }
 +
 
 +
  @Before
 +
  public void setUp() throws Exception {
 +
      /* some pre init stuff before each case */
 +
  }
 +
 
 +
  @After
 +
  public void tearDown() throws Exception {
 +
      /* useful to destroy any artifacts after your test */
 +
      new PurgeArtifacts(myRootArtifact.getChildren()).execute();
 +
      /* example how you would wrap one element to pass in */
 +
      new PurgeArtifacts(Collections.singletonList(myRootArtifact)).execute();
 +
  }
 +
 
 +
  @BeforeClass
 +
  public static void setUpOnce() throws Exception {
 +
      monitorLog = TestUtil.severeLoggingStart();
 +
  }
 +
 
 +
  @AfterClass
 +
  public static void tearDownOnce() throws Exception {
 +
      TestUtil.severeLoggingEnd(monitorLog);
 +
      /* any other final cleanup */
 +
  }
 +
}
 +
</source>
 +
 
 +
== Java Development Tips ==
 +
 
 +
=== Threading ===
 +
* Collections.synchronizedMap still requires manual synchronization on the returned map when iterating over any of its collection views.
 +
* Eclipse -> Debug Perspective -> Debug view (stacktrace view) -> white downward arrow menu -> Java -> Show Monitors
 +
:Eclipse can detect deadlocks and gives locking information needed to determine the root cause
 +
* When using a HashMap with more than one thread, use java.util.concurrent.ConcurrentHashMap instead
 +
 
 +
 
 +
== Unix Commands ==
 +
<source lang=bash>
 +
find <filename> -type f -exec chown <new_owner> {} \; -exec chmod 664 {} \;
 +
du -hs *
 +
tail -f /var/tmp/my.log
 +
netstat -an
 +
vi find and replace: s/pattern1/pattern2/g
 +
find . -exec grep -l pattern {} \;
 +
finger -wpsf <user>
 +
</source>
 +
 
 +
== SQL Examples ==
 +
 
 +
<source lang=sql>
 +
-- create a trigger that runs each time rows are deleted from osee_server_lookup
 +
 
 +
create or replace trigger osee_server_lookup_brd
 +
before delete on osee_server_lookup
 +
 
 +
for each row
 +
  begin
 +
      insert into find_user( user_name, chg_date) values (user, sysdate );
 +
  end;
 +
 
 +
-- create a synonym in the osee_client scheme to the table osee_enum_type_def owned by scheme osee and then give osee_client privileges to actually use it
 +
CREATE OR REPLACE SYNONYM osee_client.osee_enum_type_def FOR osee.osee_enum_type_def;
 +
grant select, update, insert on osee_enum_type_def to osee_client;
 +
 
 +
-- an update statement that involves another table
 +
UPDATE osee_attribute_type aty SET enum_type_id = (select et.enum_type_id from osee_enum_type et where aty.name = et.enum_type_name) where validity_xml is not null;
 +
 
 +
-- retrieve duplicate HRIDS, its GUID and Artifact Type name:
 +
SELECT t1.guid,
 +
  t1.human_readable_id,
 +
  t3.name
 +
FROM osee_artifact t1,
 +
  osee_artifact_type t3
 +
WHERE t1.human_readable_id IN
 +
  (SELECT t2.human_readable_id
 +
  FROM osee_artifact t2
 +
  GROUP BY t2.human_readable_id HAVING COUNT(t2.human_readable_id) > 1)
 +
AND t3.art_type_id = t1.art_type_id
 +
ORDER BY t1.human_readable_id;
 +
 
 +
-- retrieve the number of attributes with the specified value:
 +
-- (Note: COUNT function returns the number of rows in a query, COUNT(1) is for better performance;
 +
-- In the below example, the COUNT function does not need to retrieve all fields from the osee attribute table
 +
-- as it would if you used the COUNT(*) syntax. It will merely retrieve the numeric value of 1 for each record
 +
-- that meets your criteria)
 +
SELECT count(1) from osee_attribute where value like ?, where ? == '%<value>%'
 +
 
 +
-- retrieve the number of commit comments with the specified value:
 +
SELECT count(1) from osee_tx_details where osee_comment like ?, where ? == '%value>%'
 +
 
 +
-- retrieve the number of branch names with the specified value:
 +
SELECT count(1) from osee_branch where branch_name like ?, where ? == '%value>%'
 +
 
 +
-- retrieve all data from the specified tables on a specific artifact
 +
SELECT *
 +
FROM osee_artifact_version arv,
 +
  osee_txs txs,
 +
  osee_tx_details txd
 +
WHERE art_id = <value>
 +
AND arv.gamma_id = txs.gamma_id
 +
AND txs.transaction_id = txd.transaction_id
 +
 
 +
-- retrieve all data from the osee artifact table for the specified artifact
 +
SELECT * from osee_artifact where art_id=<value>
 +
 
 +
-- list execution plans
 +
select distinct 'explain plan set statement_id = ' || sql_id || ' for ' || sql_text || ';' as ex from v$sql where lower(sql_text) like 'select%osee_relation_link%' and sql_text not like '%DS_SVC%' and sql_text not like '%SYS.DUAL%' and parsing_schema_name = 'OSEE_CLIENT' order by ex;
 +
select * from plan_table;
 +
 
 +
</source>
 +
 
 +
== Release Engineering ==
 +
=== Eclipse.org downloads ===
 +
# use scp to connect to download1.eclipse.org with your standard committer credentials
 +
# set proxy if behind firewall
 +
# /home/data/users/<commiterId>/downloads/technology/osee
 +
 
 +
=== Managing Orbit Bundles ===
 +
* http://wiki.eclipse.org/Orbit_Builds
 +
* http://wiki.eclipse.org/Orbit_Builds#Orbit_Builds_for_Orbit_Committers
 +
* http://wiki.eclipse.org/Adding_Bundles_to_Orbit
 +
* http://wiki.eclipse.org/Orbit_Bundle_Checklist
 +
* http://build.eclipse.org:9777/dashboard/tab/builds
 +
:builds -> orbit-I -> click the circular arrow (force build)
 +
* http://download.eclipse.org/tools/orbit/committers/
 +
 
 +
* New -> Other... -> Plug-in Project
 +
:* check "Create a java project"
 +
:* "an osgi Framework": Equinox
 +
:* no activator
 +
:* Bundle Id: <my.plugin>
 +
:* Bundle-Version: 10.5.1.1_qualifier
 +
:* Name: %bundleName
 +
:* Provider:  %bundleProvider
 +
* delete .settings folder
 +
* create folder <my.plugin>/source-bundle
 +
* create folder <my.plugin>/source-bundle/META-INF
 +
* create file <my.plugin>/source-bundle/META-INF/MANIFEST.MF
 +
:* Bundle Id:  <my.plugin>.source
 +
:* Eclipse-SourceBundle:  <my.plugin>
 +
 
 +
* create file <my.plugin>/readme.txt
 +
* copy plugin.properties to <my.plugin>/plugin.properties
 +
:* update bundleName
 +
*copy <my.plugin>/plugin.properties to <my.plugin>/source-bundle/plugin.properties
 +
* copy about.html to <my.plugin>/about.html
 +
* create folder <my.plugin>/about_files
 +
:* copy licensing text files here
 +
 
 +
* extract content of binary jar file into root of <my.plugin> (do not over-write MANIFEST.MF)
 +
:* select project in workspace -> context menu -> Refresh
 +
 
 +
* Manifest editor -> Build tab
 +
:* check <my.plugin>/about.html under both your Binary Build and Source Build
 +
:* check <my.plugin>/about_files under both your Binary Build and Source Build
 +
:* check <my.plugin>/plugin.properties
 +
:* check <my.plugin>/<class folder>
 +
 
 +
* copy <my.plugin>/about.html to <my.plugin>/source-bundle/about.html
 +
* copy <my.plugin>/about_files to <my.plugin>/source-bundle/about_files
 +
 
 +
* context menu on <my.plugin> -> Properties -> Java Build Path
 +
:* Source Tab -> remove all source folders
 +
:* Libraries -> Add class Folder ... -> select root project
 +
::* expand newly added class folder and select source attachment -> Edit... -> Workspace... -> /<my.plugin>/source-bundle
 +
:* Order and Export -> ensure libraries and class folders are marked exported
 +
 
 +
* edit <my.plugin>/.project
 +
:* add a space and then the 3 part version number to the project name
 +
* edit <my.plugin>/build.properties
 +
:* ensure exists: output.. = . and remove source.. = .
 +
* edit <my.plugin>/META-INF/MANIFEST.MF:
 +
:* add line: Bundle-Localization: plugin
 +
* copy source to <my.plugin>/source-bundle/
 +
* copy <my.plugin>/build.properties to <my.plugin>/source-bundle/build.properties
 +
:* add to bin.includes the root directory of the source (i.e. org, com, etc.)
 +
:* Note: the source bundle's build.properties entries must be relative to <my.plugin>/source-bundle/ (rather than just <my.plugin>/)
 +
 
 +
* context menu on <my.plugin> -> Team -> Share Project... -> CVS -> "dev.eclipse.org/cvsroot/tools"
 +
:* Use specified module name -> org.eclipse.orbit/<my.plugin>
 +
:* uncheck Launch the Commit wizard
 +
* context menu on <my.plugin>/readme.txt and <my.plugin>/.project -> Team -> Commit... -> "initial project creation"
 +
 
 +
* select project in workspace -> context menu -> Team > Branch...
 +
:* "v<version number>" where <version number> original libraries version with  '.' s replaced with '_' . (i.e. version is 2.3 would go in the v2_3 branch)
 +
:* check "Work with this branch"
 +
* delete <my.plugin>/readme.txt
 +
 +
* CVS check out org.eclipse.orbit/org.eclipse.orbit.build.feature.set1
 +
* edit /org.eclipse.orbit.build.feature.set1/feature.xml
 +
:* add plugin
 +
:* set download-size and install-size
 +
 +
* CVS check out org.eclipse.orbit/org.eclipse.orbit.releng
 +
* edit /org.eclipse.orbit.releng/maps/bundles.map
 +
:* plugin@org.apache.derby.net,10.5.1=CVS,tag=v200910011000,cvsRoot=:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,path=org.eclipse.orbit/org.apache.derby.net
 +
:* plugin@org.apache.derby.net.source,10.5.1=CVS,tag=v200910011000,cvsRoot=:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,path=org.eclipse.orbit/org.apache.derby.net/source-bundle
 +
:* if you edited /org.eclipse.orbit.build.feature.set1/feature.xml, then update the map file's tag also (so the updated version will be used)
 +
 +
* context menu on <my.plugin> -> Team -> Commit...
 +
* context menu on <my.plugin> -> Team -> Tag as Version...  use the CVS tag you put in the map file
 +
* context menu on org.eclipse.orbit.build.feature.set1 -> Team -> Tag as Version... (if you changed it)
 +
* edit /org.eclipse.orbit.releng/psf/orbit.psf
 +
* Update the IP Log
 +
 
 +
 
 +
 
 +
[[Integrating OSEE and Bugzilla|'''Integrating OSEE and Bugzilla''']]
  
 
[[Category:OSEE]]
 
[[Category:OSEE]]

Revision as of 17:03, 2 June 2011

Before Committing Code

  1. Synchronize and Update
  2. Run Code Quality Checks
  3. Ensure all the tests are green. (Tests projects can be identified by their '*.test' suffix. All tests have to be executed as plug-in unit tests.)
  4. Ensure the reference documentation is up to date (i.e. reflects your changes) (Documentation is maintained in project 'via the OSEE wiki').

Code Quality Tools

Update your eclipse installation with the following tools:

Installation for Find Bugs, PMD, Emma, and Check Style:

  1. Launch Eclipse and go to Help->Software Updates->Available Software
  2. Drag the Update Site URLs into the Software Update and Add-ons dialog
  3. Select code style tools to install - for Find Bugs make sure you only select the Eclipse 3.4 or later entry
  4. Click the Install button
  5. Once installation completes, restart eclipse

Code Quality Configuration

Import OSEE Team Preferences

  1. Right-click on the following link OSEE Team Preferences
  2. Select Save Link As
  3. Enter osee_team_preferences.epf and click Save
  4. Launch Eclipse
  5. Select File->Import
  6. Open the General folder
  7. Select Preferences
  8. Click on the Browse... button, navigate to the location where you saved osee_team_preferences.epf
  9. Select Import all
  10. Click Finish to import settings

Check Style Configuration

  1. Select Window->Preferences
  2. Select Checkstyle
  3. Under the General Settings set Rebuild projects if needed to always
  4. Under the Global Check Configurations, click the New button
  5. Select Remote Configuration under the Type drop down
  6. Set name to OSEE Checks (Eclipse)
  7. Copy the following link into the Location entry OSEE Checks (Eclipse)
  8. Set the Cache configuration file checkbox to true
  9. Click OK
  10. Select the OSEE Checks (Eclipse) configuration and click on Set as Default
  11. Click OK to accept settings

Find Bugs Configuration

  1. Select Window->Preferences->Java
  2. Select Find Bugs
  3. Set analysis effort to Default
  4. Click OK to accept settings

PMD Configuration

  1. Right-click on the following link OSEE PMD Rule Set
  2. Select Save Link As
  3. Enter osee_pmd_rule_set.xml and click Save
  4. In Eclipse, select Window->Preferences
  5. Select PMD->Rules Configuration
  6. Click on Import rule set...
  7. Click on Browse, navigate to the location where you saved osee_pmd_rule_set.xml
  8. Set the Import by Copy check box to true
  9. Select OK to import the rule set
  10. Select OK to accept the change and close the Preferences Dialog

Monitor OSEE Bugs using Mylyn

See Integrating OSEE and Bugzilla.

Coding Standards

Utility Classes

In order to optimize reuse of code, OSEE developers have adopted a set of standards.

Utility classes should:

  1. Be named xxxUtil. This allows for each searching and location by looking for *Util. This excludes stand-alone utility classes like HashCollection or CountingMap.
  2. As much as possible, be located in a package postfix'd with .util. eg. org.eclipse.osee.ats.util
  3. Should contain static methods

Cleanup of existing utility methods

The following needs to be done:

  1. Create set of common utility class names
  2. Move utilities to their respective places
  3. Either deprecate or replace uses of old locations

Comments

Most comments offer more clutter than information, especially non-Javadoc comments which can be removed using the following regular expression \R[ \t]*/\*\s+[\* ]*\(non-Javadoc\)[^/]+/.

Regular Expression Find/Replace application of standards

  • ([^ ]+) != null && !(\1).equals\(""\) replace with Strings.isValid($1)
  • ([^ ]+) == null \|\| (\1).equals\(""\) replace with !Strings.isValid($1)

OSEE Master Test Suite

OSEE uses JUnit 4 for its test suites. Some links to get started:

Use Cases

Requirements of the OSEE test suite:

  1. Single button press to run all tests
  2. Minimal number of launch configurations to maintain
  3. Ability for any user, internal or external, to easily run a suite of tests before commit
  4. Continuous integration (checkout, build, test, report)
  5. Use JUnit framework for all testing
  6. Enable health checks against production database to be part of test suite
  7. New test cases can be added easily

Running the OSEE Test Suite

The OSEE test suite uses the org.eclipse.osee.ats.config.demo plugin to initialize a demo database, populate it with demo data and run the majority of the OSEE tests against this common data set.

These tests are contributed to the MasterTestSuite groups using Eclipse's extension point framework. Any Test Suite can implement IOseeTest and extend the OseeTest extension point to be contributed to the appropriate test suite(s).

Steps to test

  1. Checkout org.eclipse.osee.ats.config.demo
  2. Checkout org.eclipse.osee.support.test
  3. Run the following tests in order and resolve any errors:
    1. Run the Demo database tests:
      1. Run the OSEE Demo Application Server launch config
      2. Run the MasterTestSuite_DemoDbInit launch config. This initializes the postgres database for demo populate and tests
      3. Run the MasterTestSuite_DemoDbPopulate launch config. This loads the database with branches, actions and sets conditions for populate tests.
      4. Run the MasterTestSuite_DemoDbTests launch config. This runs tests against the DemoDb Populated database.
      5. Stop the OSEE Demo Application Server if still running
    2. Run the Production TestDb tests:
      1. Run the OSEE Application Server launch config.
      2. Run the MasterTestSuite_TestDbInit launch config. This initializes the postgres database for production testdb tests
      3. Run the MasterTestSuite_TestDbTests launch config. - This runs production specific tests using a TestDb.
    3. Run the Production tests and health checks against the current production release
      1. Run the MasterTestSuite_ProductionTests launch config. This runs tests and health checks against the current production released database.

Common test utility plugin

The plugin org.eclipse.osee.support.test.util is in support of our testing framework. It has a number of common enums and a TestUtil class that should be used by any junit tests. The intent is to keep this plugin lightweight and without many dependencies cause all the testing fragments "should" include it. In addition, it should not be included by any production plugins, only test fragments.

Adding new Tests to MasterTestSuite

To create test fragment off plugin to be tested

All OSEE JUnit tests should live in a fragment of the plugin to be tested.

  1. Select plugin to be tested
  2. Right-click -> New Project -> Plugin Project -> Plugin Fragment
  3. Enter plugin to be tested as Host plugin
  4. Complete wizard
  5. In plugin to be tested (eg org.eclipse.osee.ats)
    1. Add "Eclipse-ExtensibleAPI: true" to MANIFEST.MF of plugin to be tested. This allows test suites to see tests in this plugin
  6. In new fragment (eg org.eclipse.osee.ats.test)
    1. Add org.junit4 (make sure junit4, not junit) to dependencies
    2. Add the common test utility plugin org.eclipse.osee.support.test.util plugin to dependencies
    3. Export packages containing TestCases and TestSuites
  7. In MasterTestSuite plugin (eg org.eclipse.osee.support.test)
    1. Add dependency on plugin to be tested (ge org.eclipse.osee.ats)
    2. Add test cases and suites from fragment to appropriate MasterTestSuite java Test Suites

To add a new JUnit TestCase

  1. Write the TestCase to run against a database populated with DemoDbInit and DemoDbPopulate
  2. Add the TestCase to an existing MasterTestSuite_DemoDbTests test suite

Things to consider

  1. Your tests must clean-up after themselves to ensure that the entire test suite can be run.
  2. Do not assume order of execution except within your own Test Suite

Master Test Suite - Frequently Asked Questions

What do I need for every test case?

  • import static org.junit.Assert.*;
  • In setup method (@Before), always assert that you are on correct database by adding one of these
assertTrue("Should be run on production datbase.", TestUtil.isProductionDb());
assertTrue("Should be run on test datbase.", TestUtil.isTestDb());
assertTrue("Should be run on demo datbase.", TestUtil.isDemoDb());
  • In setup method (@Before), always assert that you have correct app server running *
assertTrue("Demo Application Server must be running.",
  ClientSessionManager.getAuthenticationProtocols().contains("demo"));
assertTrue("Client must authenticate using demo protocol",
   ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
 
assertFalse("Application Server must be running.",
   ClientSessionManager.getAuthenticationProtocols().contains("demo"));
assertFalse("Client can't authenticate using demo protocol",
   ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
}

Why do I get an exception on synchronized-lock when I launch the tests

The launch configuration does not have all plugins necessary to run.

  1. Open Debug Configurations for that launch item
  2. Go to plugins tab and select "Validate Plugins". This will show if any plugins are missing from selected items.
  3. Select "Add Required Plugins" to add them.
  4. Re-launch.

Why do I get exceptions that cycle was detected when I add things to the org.eclipse.osee.test.util plugin

This plugin is meant to be extremely light-weight and only provide simple statics and methods to all the test plugins. Because it has to be included in all test fragments from jdk.core all the way up to framework.ui (skynet.ui), it can not depend on any of the higher level plugins or cycles will occur. Remove these dependencies and cycles will be fixed.

How do I timeout a test?

Define a timeout period in miliseconds with “timeout” parameter. The test fails when the timeout period exceeds. view

@Test(timeout = 1000)  
public void infinity() {  
    while (true);  
}

How do I test exception handling

Exception Handling Use “expected” paramater with @Test annotation for test cases that expect exception. Write the class name of the exception that will be thrown. view plainprint?

@Test(expected = ArithmeticException.class)  
public void divisionWithException() {  
   // divide by zero  
   simpleMath.divide(1, 0);  
}

To add a new JUnit TestSuite

  1. Create a fragment for the plugin (see above)
  2. Create new JUnit TestCases as above
  3. Create a new JUnit TestSuite
  4. Add new TestSuite to one of the MasterTestSuite java test suites

Common test cases

/*
    COMPANY DISTRIBUTION STATEMENT
*/
 
package com.company.component.testcase;
 
import
...
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
 
/**
 * @link <link_to_class_under_test>
 * @author <you>
 */
public final class MySuperbTest {
 
   private static SevereLoggingMonitor monitorLog = null;
   private static Artifact myRootArtifact = null;
 
   @Test
   public void importSimpleArtifacts() throws Exception {
      Assert.assertTrue("Some message...", conditionToBeTrue);
   }
 
   @Before
   public void setUp() throws Exception {
      /* some pre init stuff before each case */
   }
 
   @After
   public void tearDown() throws Exception {
      /* useful to destroy any artifacts after your test */
      new PurgeArtifacts(myRootArtifact.getChildren()).execute();
      /* example how you would wrap one element to pass in */
      new PurgeArtifacts(Collections.singletonList(myRootArtifact)).execute();
   }
 
   @BeforeClass
   public static void setUpOnce() throws Exception {
      monitorLog = TestUtil.severeLoggingStart();
   }
 
   @AfterClass
   public static void tearDownOnce() throws Exception {
      TestUtil.severeLoggingEnd(monitorLog);
      /* any other final cleanup */
   }
}

Java Development Tips

Threading

  • Collections.synchronizedMap still requires manual synchronization on the returned map when iterating over any of its collection views.
  • Eclipse -> Debug Perspective -> Debug view (stacktrace view) -> white downward arrow menu -> Java -> Show Monitors
Eclipse can detect deadlocks and gives locking information needed to determine the root cause
  • When using a HashMap with more than one thread, use java.util.concurrent.ConcurrentHashMap instead


Unix Commands

find <filename> -type f -exec chown <new_owner> {} \; -exec chmod 664 {} \;
du -hs *
tail -f /var/tmp/my.log
netstat -an
vi find and replace: s/pattern1/pattern2/g
find . -exec grep -l pattern {} \;
finger -wpsf <user>

SQL Examples

-- create a trigger that runs each time rows are deleted from osee_server_lookup
 
CREATE OR REPLACE TRIGGER osee_server_lookup_brd
BEFORE DELETE ON osee_server_lookup
 
FOR each ROW
   BEGIN
      INSERT INTO find_user( user_name, chg_date) VALUES (USER, sysdate );
   END;
 
-- create a synonym in the osee_client scheme to the table osee_enum_type_def owned by scheme osee and then give osee_client privileges to actually use it
CREATE OR REPLACE SYNONYM osee_client.osee_enum_type_def FOR osee.osee_enum_type_def;
GRANT SELECT, UPDATE, INSERT ON osee_enum_type_def TO osee_client;
 
-- an update statement that involves another table
UPDATE osee_attribute_type aty SET enum_type_id = (SELECT et.enum_type_id FROM osee_enum_type et WHERE aty.name = et.enum_type_name) WHERE validity_xml IS NOT NULL; 
 
-- retrieve duplicate HRIDS, its GUID and Artifact Type name:
SELECT t1.guid,
  t1.human_readable_id,
  t3.name
FROM osee_artifact t1,
  osee_artifact_type t3
WHERE t1.human_readable_id IN
  (SELECT t2.human_readable_id
   FROM osee_artifact t2
   GROUP BY t2.human_readable_id HAVING COUNT(t2.human_readable_id) > 1)
AND t3.art_type_id = t1.art_type_id
ORDER BY t1.human_readable_id;
 
-- retrieve the number of attributes with the specified value: 
-- (Note: COUNT function returns the number of rows in a query, COUNT(1) is for better performance;
-- In the below example, the COUNT function does not need to retrieve all fields from the osee attribute table 
-- as it would if you used the COUNT(*) syntax. It will merely retrieve the numeric value of 1 for each record
-- that meets your criteria)
SELECT COUNT(1) FROM osee_attribute WHERE VALUE LIKE ?, WHERE ? == '%<value>%'
 
-- retrieve the number of commit comments with the specified value:
SELECT COUNT(1) FROM osee_tx_details WHERE osee_comment LIKE ?, WHERE ? == '%value>%'
 
-- retrieve the number of branch names with the specified value:
SELECT COUNT(1) FROM osee_branch WHERE branch_name LIKE ?, WHERE ? == '%value>%'
 
-- retrieve all data from the specified tables on a specific artifact 
SELECT *
FROM osee_artifact_version arv,
  osee_txs txs,
  osee_tx_details txd
WHERE art_id = <value>
 AND arv.gamma_id = txs.gamma_id
 AND txs.transaction_id = txd.transaction_id
 
-- retrieve all data from the osee artifact table for the specified artifact 
SELECT * FROM osee_artifact WHERE art_id=<value>
 
-- list execution plans
SELECT DISTINCT 'explain plan set statement_id = ' || sql_id || ' for ' || sql_text || ';' AS ex FROM v$sql WHERE LOWER(sql_text) LIKE 'select%osee_relation_link%' AND sql_text NOT LIKE '%DS_SVC%' AND sql_text NOT LIKE '%SYS.DUAL%' AND parsing_schema_name = 'OSEE_CLIENT' ORDER BY ex;
SELECT * FROM plan_table;

Release Engineering

Eclipse.org downloads

  1. use scp to connect to download1.eclipse.org with your standard committer credentials
  2. set proxy if behind firewall
  3. /home/data/users/<commiterId>/downloads/technology/osee

Managing Orbit Bundles

builds -> orbit-I -> click the circular arrow (force build)
  • New -> Other... -> Plug-in Project
  • check "Create a java project"
  • "an osgi Framework": Equinox
  • no activator
  • Bundle Id: <my.plugin>
  • Bundle-Version: 10.5.1.1_qualifier
  • Name: %bundleName
  • Provider:  %bundleProvider
  • delete .settings folder
  • create folder <my.plugin>/source-bundle
  • create folder <my.plugin>/source-bundle/META-INF
  • create file <my.plugin>/source-bundle/META-INF/MANIFEST.MF
  • Bundle Id: <my.plugin>.source
  • Eclipse-SourceBundle: <my.plugin>
  • create file <my.plugin>/readme.txt
  • copy plugin.properties to <my.plugin>/plugin.properties
  • update bundleName
  • copy <my.plugin>/plugin.properties to <my.plugin>/source-bundle/plugin.properties
  • copy about.html to <my.plugin>/about.html
  • create folder <my.plugin>/about_files
  • copy licensing text files here
  • extract content of binary jar file into root of <my.plugin> (do not over-write MANIFEST.MF)
  • select project in workspace -> context menu -> Refresh
  • Manifest editor -> Build tab
  • check <my.plugin>/about.html under both your Binary Build and Source Build
  • check <my.plugin>/about_files under both your Binary Build and Source Build
  • check <my.plugin>/plugin.properties
  • check <my.plugin>/<class folder>
  • copy <my.plugin>/about.html to <my.plugin>/source-bundle/about.html
  • copy <my.plugin>/about_files to <my.plugin>/source-bundle/about_files
  • context menu on <my.plugin> -> Properties -> Java Build Path
  • Source Tab -> remove all source folders
  • Libraries -> Add class Folder ... -> select root project
  • expand newly added class folder and select source attachment -> Edit... -> Workspace... -> /<my.plugin>/source-bundle
  • Order and Export -> ensure libraries and class folders are marked exported
  • edit <my.plugin>/.project
  • add a space and then the 3 part version number to the project name
  • edit <my.plugin>/build.properties
  • ensure exists: output.. = . and remove source.. = .
  • edit <my.plugin>/META-INF/MANIFEST.MF:
  • add line: Bundle-Localization: plugin
  • copy source to <my.plugin>/source-bundle/
  • copy <my.plugin>/build.properties to <my.plugin>/source-bundle/build.properties
  • add to bin.includes the root directory of the source (i.e. org, com, etc.)
  • Note: the source bundle's build.properties entries must be relative to <my.plugin>/source-bundle/ (rather than just <my.plugin>/)
  • context menu on <my.plugin> -> Team -> Share Project... -> CVS -> "dev.eclipse.org/cvsroot/tools"
  • Use specified module name -> org.eclipse.orbit/<my.plugin>
  • uncheck Launch the Commit wizard
  • context menu on <my.plugin>/readme.txt and <my.plugin>/.project -> Team -> Commit... -> "initial project creation"
  • select project in workspace -> context menu -> Team > Branch...
  • "v<version number>" where <version number> original libraries version with '.' s replaced with '_' . (i.e. version is 2.3 would go in the v2_3 branch)
  • check "Work with this branch"
  • delete <my.plugin>/readme.txt
  • CVS check out org.eclipse.orbit/org.eclipse.orbit.build.feature.set1
  • edit /org.eclipse.orbit.build.feature.set1/feature.xml
  • add plugin
  • set download-size and install-size
  • CVS check out org.eclipse.orbit/org.eclipse.orbit.releng
  • edit /org.eclipse.orbit.releng/maps/bundles.map
  • plugin@org.apache.derby.net,10.5.1=CVS,tag=v200910011000,cvsRoot=:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,path=org.eclipse.orbit/org.apache.derby.net
  • plugin@org.apache.derby.net.source,10.5.1=CVS,tag=v200910011000,cvsRoot=:pserver:anonymous@dev.eclipse.org:/cvsroot/tools,path=org.eclipse.orbit/org.apache.derby.net/source-bundle
  • if you edited /org.eclipse.orbit.build.feature.set1/feature.xml, then update the map file's tag also (so the updated version will be used)
  • context menu on <my.plugin> -> Team -> Commit...
  • context menu on <my.plugin> -> Team -> Tag as Version... use the CVS tag you put in the map file
  • context menu on org.eclipse.orbit.build.feature.set1 -> Team -> Tag as Version... (if you changed it)
  • edit /org.eclipse.orbit.releng/psf/orbit.psf
  • Update the IP Log


Integrating OSEE and Bugzilla