We celebrated our 7th anniversary few days back. We had to go to the 59 to join the party. Below are some memories from that. These are captured by one of our interns, Lasindu Charith. I can call him the official photographer in WSO2, at least among interns :P
It was a little party:) But there was enough food too :D
And one lucky guy got to celebrate his birthday on the same day!!
Tuesday, August 14, 2012
WSO2 7th Anniversary Celebrations
Things that you should remember when test automating(best practices)
Less Hard-coding
We are always tempted to hardcode
things. It make our life easy. But this can make maintaining that
code a big issue. I had to change some of the places that I did
hardcode due to different reasons.
Dates and times
When working with date and times you
might forget that, those things are changing. I did this mistake ones
in the testing. I was asked to test the service locking
functionality. We can lock a service for a specific time. I just
hard-corded the dates and times and did the testing. Soon I realized
that, if we are going to use them in the future, test going to fail.
You might think that is foolish from me, but believe me we miss those
little things while cording.
Use of Constants
If you really need to hardcode
something do it through a constant, at the bigging of the code. So if
it get changed, it is easy for someone else to find and change it
Do not leave thing behind
When you create any objects for testing
and if you have done any configuration changes to the product for
testing, make sure you undone them before you leave. Those objects
and changes can break other tests by other users. You can use
@AfterClass for that purpose.
Avoid Test anti-patterns
Just search for the test anti-patterns
and you will find lot of them that you should avoid, or at least try
to avoid.
Coverage Vs Stable Product
When we are testing, we normally get
blinded by the coverage. But always our goal should be to build a
stable product. No matter what is the test coverage if our product is
failing, all the hard work is for nothing. This is told to me by our
team lead Krishantha ayya.
Good Articles
Clarity Framework
Based on the training session and the
slide-set provided by Dharshana,
and Krishantha.
Clarity is a easy and optimized way to
do the integration testing. It can automate platform-wide scenarios ,
execute tests against stratos and private clouds, adopt
tooling(Selenium , SoapUI , Jmeter , Ravana, WSO2 Ravana is an
opensource benchmark test framework that aims to facilitate
performance benchmarks of different servers. ) support to automation
, do reporting and keeping historical records.
Architecture
Work similar to TestNG.
- This is the component level view of the architecture.
More information:
TestNg documenation :
http://testng.org/doc/documentation-main.html
Monday, August 13, 2012
Beginning the Test Automation
We got this order to freeze our current
project and join the test automation project, which was lead by
Krishantha Samaraweera. 23 of us were divided in to 2 groups and
assigned two of our major products, ESB and GREG. I am in the GREG
test automation team. Here we are using a test framework called as
'Clarity'. Clarity was wso2 built testing framework which can be used
to test our own products. Clarity is still under development. I will
talk more about this framework in one of my future posts.
All the tests that we are writing is
submitted as patches to the public jira project 'Test Automation'.
Our team lead take a look at that and apply them to the main
trunk/branch as we are not having committer rights. I will elaborate
more on this jira thing and patch submission in my future posts.
We have to adhere to the standard
coding style that is used in wso2. I have posted on this matter
earlir in this blog. How to use the style xml to configure eclipse.
You can find that post here.
We used the remote debugging that is available in the IDE to test or
patches. You can find my article on remote debugging here.
This was a nice learning curve for all
of us. We went through lot of training sessions and was informed with
best practices when testing, which were great additions to our
knowledge. And it was a new place I was in 59 branch and now I am in
58 branch. And I must mention that here the TT table is far better
than what we had in 59. After all this is temporary, I will return to
the 59 after this test automation thing is done.
Labels:
Coding Styles,
remote debugging,
romesh malinga perera,
wso2
Tuesday, July 10, 2012
Using OSGi console to debug things
This OSGi console was very helpful to
me in finding out problems relevant to OSGi bundles. You can have lot
of information about this in the Internet. In here what I am going to
write is about how I used it in the debugging.
First start the server with following
option
-DosgiConsole. This will start the
server with OSGi console. This is very helpful in situations like,
checking whether all bundles that you put in to droppings have
activated. When the server starts. Put ss in console. This will give
a list of all bundles.
Use it with 'like' modifier to get the
relevant bundles only. Ex ss like student
Now you can see state of all bundles.
With the installation of a bundle in the OSGi runtime this bundle is
persisted in a local bundle cache. The OSGi runtime then tries to
resolve all dependencies of the bundle.If all required dependencies
are resolved the bundle is in the status RESOLVED otherwise it is in
the status INSTALLED.
If several bundles exist which would
satisfy the dependency, then the bundle with the highest version is
used. If the versions are the same, then the bundle with the lowest
ID will be used. If the bundle is started, its status is STARTING.
Afterwards it gets the ACTIVE status. -
(http://www.vogella.com/articles/OSGi/article.html#osgiarch_bundles
good reference)
You have to have all your bundles
acticvated. If not check what is wrong with them using 'bundle
<bundle number>' command. If there is no error, try starting it
manually using 'start <bundle number>'
Monday, July 9, 2012
Publishing to BAM
I created this just to publish data I
collect to BAM, so this do not adhere to good programming practices.
package org.wso2.carbon.usage.agent.util;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.security.sasl.AuthenticationException;
import org.wso2.carbon.eventbridge.agent.thrift.Agent;
import org.wso2.carbon.eventbridge.agent.thrift.DataPublisher;
import org.wso2.carbon.eventbridge.agent.thrift.conf.AgentConfiguration;
import org.wso2.carbon.eventbridge.agent.thrift.exception.AgentException;
import org.wso2.carbon.eventbridge.commons.Event;
import org.wso2.carbon.eventbridge.commons.exception.DifferentStreamDefinitionAlreadyDefinedException;
import org.wso2.carbon.eventbridge.commons.exception.MalformedStreamDefinitionException;
import org.wso2.carbon.eventbridge.commons.exception.NoStreamDefinitionExistException;
import org.wso2.carbon.eventbridge.commons.exception.StreamDefinitionException;
import org.wso2.carbon.eventbridge.commons.exception.TransportException;
public class PublishUtil2 {
public static final String STREAM_NAME1 = "org.wso2.db6.kpiii";
public static final String VERSION1 = "1.0.6";
private static String streamId1;
private static DataPublisher dataPublisher = null;
public static void publish(long exceededBytes, long databasesize, String tenentdomain) throws AgentException, MalformedStreamDefinitionException,
StreamDefinitionException, DifferentStreamDefinitionAlreadyDefinedException, MalformedURLException,
AuthenticationException, NoStreamDefinitionExistException,
org.wso2.carbon.eventbridge.commons.exception.AuthenticationException, TransportException, SocketException, UnknownHostException{
System.out.println("Starting BAM KPI Agent");
AgentConfiguration agentConfiguration = new AgentConfiguration();
String currentDir = System.getProperty("user.dir");
System.setProperty("javax.net.ssl.trustStore", currentDir + "/repository/resources/security/client-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
Agent agent = new Agent(agentConfiguration);
dataPublisher = null;
try {
dataPublisher = new DataPublisher("tcp://10.100.3.80:7613", "admin", "admin", agent);
} catch (Throwable e){
e.printStackTrace();
}
streamId1 = null;
try {
streamId1 = dataPublisher.findEventStream(STREAM_NAME1, VERSION1);
System.out.println("Stream already defined");
} catch (NoStreamDefinitionExistException e) {
streamId1 = dataPublisher.defineEventStream("{" +
" 'name':'" + STREAM_NAME1 + "'," +
" 'version':'" + VERSION1 + "'," +
" 'nickName': 'DSSUsage'," +
" 'description': 'Exceeded DB Use'," +
" 'metaData':[" +
" {'name':'clientType','type':'STRING'}" +
" ]," +
" 'payloadData':[" +
" {'name':'exceededBytes','type':'LONG'}," +
" {'name':'databasesize','type':'LONG'}," +
" {'name':'tenentdomain','type':'STRING'}" +
" ]" +
"}");
}
//Publish event for a valid stream
if (!streamId1.isEmpty()) {
System.out.println("Stream ID: " + streamId1);
publishEvents(tenentdomain, exceededBytes, databasesize);
// for (int i = 0; i < 1; i++) {
// publishEvents("malinga");
// System.out.println("Events published : " + (i + 1) * 2);
// }
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// }
dataPublisher.stop();
}
}
public static void publishEvents(String name, long exceededBytes, long databasesize) throws AgentException {
System.out.println(name);
publishEvents(dataPublisher, streamId1, name, exceededBytes, databasesize);
}
public static void publishEvents(DataPublisher dataPublisher, String streamId, String name, long exceededBytes, long databasesize) throws AgentException {
Event eventOne = new Event(streamId, System.currentTimeMillis(), new Object[]{"external"}, null,
new Object[]{exceededBytes, databasesize, 3600.0, name});
dataPublisher.publish(eventOne);
}
}
Problems I had to face.
I tried to change the streamId1, but
it was not possible. It gave a error in BAM side. Then I got to know
that schema is saved under the STREAM_NAME1, and if I want to change
it, I have to do that with a change in STREAM_NAME1 too.
There was no way to check the the
published data as it would show some rubbish, in the data viewer in
BAM. I got a nice client for one of my mentors that can get the data
from Cassandra cluster. This is written by 'Shariq Muhammed', he is a
software engineer at WSO2. This is also written just to read the data
and he haven't thought much about adhering to good programming
practices. You can have it from below link
First I couldn't sent long, It took me
a while to figure that out. It was because the number I send was
taken as a int. I had to add the 'L' to end of it to get it working.
Labels:
BAM2,
publish,
romesh malinga perera,
rss,
rss manager,
wso2,
WSO2 Data Services Server
OSGi Services
Full system(carbon core + products) is
built as a combination of OSGi bundles. Some of theses bundles expose
services at OSGi level. I have to use them to get the tenant usage
plan.
There is a service in manager which
gives the usage plan of the tenant. To use it first I have to catch
them, unluckily those manager component that is needed for the
service it not there in the DSS, so we have to add them to DSS
temporary as a feature. core and mgt are placed in DSS as a feature.
First we thought is putting those to into droppings. But it didn't
work as mgt package tried to start before core which is not possible
as it requires core. Because of that we have to make it as a feature.
After putting them we have catch that
service. Those are normally catches at serviceComponents(one class
with 'activate' method). Below is how I did it. There are some
methods that is used to bind and unbind the service objects we have
to have them where we catch the service
I added the osgi comments as below
/** * @scr.component name="org.wso2.carbon.rssmanager" immediate="true" * @scr.reference name="default.tenant.billing.service" * interface="org.wso2.carbon.stratos.common.TenantBillingService" * cardinality="1..1" policy="dynamic" * bind="setTenantBillingService" * unbind="unsetTenantBillingService" * @scr.reference name="user.realmservice.default" * interface="org.wso2.carbon.user.core.service.RealmService" * cardinality="1..1" policy="dynamic" * bind="setRealmService" * unbind="unsetRealmService" */then I added following methods
/**
* osgi bind method for RealmService
* @param tenantBillingService
*/
protected void setRealmService(RealmService realmService) {
this.realmService = realmService;
}
/**
* osgi unbind method for RealmService
* @param tenantBillingService
*/
protected void unsetRealmService(RealmService realmService) {
this.realmService =null;
}
/**
* returns a RealmService objects that is used to get the tenant list.
* @param tenantBillingService
*/
private RealmService getRealmService() {
return realmService;
}
After catching it I can use it as below,if(realmService!=null){
TenantManager tenantManager = getRealmService().getTenantManager();
Tenant[] tenants;
try {
tenants = (Tenant[]) tenantManager.getAllTenants();
for (int i = 0; i < tenants.length; i++) {
// check for each tenant
}
} catch (UserStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else{
System.out.println("realmService NULL");
}
Problems came across
Service was not available in DSS
First I tried to catch this in my own java class (not in RSSManagerServiceComponent) which was OK but was not the standard. Standard is to catch it in RSSManagerServiceComponent. Anyway it should work, on matter how we do it. In my case it didn't work for tenant.billing.service . Problem was same service (tenant.billing.service not realmservice) was caught in RSSManagerServiceComponent before coming in to my class. This is where I figured out the importance of that standard.
Had to include lot of other jar files in droppings.
Subscribe to:
Posts (Atom)







