Use the sample test program to perform load testing of MBS in Sybase Unwired Platform with LoadRunner.
codegen -output <outputDir> -mbs -cs -client -domain testdomain -sqlite <deployment_unit.xml>
The following is the example code for vuser_init.cs. USER_IDENTIFIER = "Client-2" assigns a constant value to allow the program to run in Visual Studio. Although different VUs have their own directory and database file, because the connection profile is shared you must avoid calling ConnectionProfile.save().
vuser_init.cs //--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : //--------------------------------------------- using System; using System.IO; using Sybase.UnwiredPlatform; using Sybase.UnwiredPlatform.Data; using Sybase.Mobile.Framework; using Sybase.Mobile; using Sybase.MessagingClientLib; using Sybase.Persistence; using Sybase.Reflection; using Sample; using LoadRunner; namespace Script { public partial class VuserClass { // Connection Information for SAP Mobile Server private const String USERNAME = "supAdmin"; private const String PASSWORD = "s3pAdmin"; private const String HOST = "10.172.85.200"; //"PALN00527192A"; private const int PORT = 5011; // typically 5001 // Registration timeout in seconds private const int TIMEOUT = 60; // The Messaging Client Application private Sybase.Mobile.Application app; private String USER_IDENTIFIER; private String USER_DATA_DIRECTORY; public int vuser_init() { // initialize this instance to identifie separate users USER_IDENTIFIER = "Client" + lr.vuser_id.ToString(); //USER_IDENTIFIER = "Client-2"; USER_DATA_DIRECTORY = Directory.GetCurrentDirectory() + "\\" + USER_IDENTIFIER; // initialize client library app = Sybase.Mobile.Application.GetInstance(USER_IDENTIFIER, USER_DATA_DIRECTORY); app.ApplicationIdentifier = "Sample"; ConnectionProfile cp = SampleDB.GetConnectionProfile(); cp.SetProperty("databaseFile", USER_DATA_DIRECTORY + "\\database.udb"); //don't call cp.Save() otherwise multiple vu will contend on the same .scp file //cp.Save(); //Make sure databaseFile peroperty on the connection profile is setup before setApplication //because SetApplication will create the database SampleDB.SetApplication(app); SampleDB.GetSynchronizationProfile().ServerName = HOST; ConnectionProperties connProps = app.ConnectionProperties; LoginCredentials loginCredentials = new LoginCredentials(USERNAME, PASSWORD); connProps.LoginCredentials = loginCredentials; connProps.ServerName = HOST; connProps.PortNumber = PORT; if (app.RegistrationStatus != RegistrationStatus.REGISTERED) { lr.start_transaction("Register Application"); app.RegisterApplication(TIMEOUT); lr.end_transaction("Register Application", lr.AUTO); } { app.StartConnection(TIMEOUT); } return 0; } } }
The following is the example code for Action.cs. The test code subscribes to the package you deployed to the server, waits for the server to push the data, and when all data are imported, continues the main thread and executes a findAll method. You can add more test code such as CUD (create, update, and delete) operations. The lr.think_time(1) call inserts think time between actions and can be configured dynamically in the runtime settings.
//--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : //--------------------------------------------- using Sybase.UnwiredPlatform; using Sybase.UnwiredPlatform.Data; using Sybase.Mobile.Framework; using Sybase.Mobile; using Sybase.MessagingClientLib; using Sybase.Persistence; using Sybase.Reflection; using LoadRunner; using System.Threading; using Sample; namespace Script { public partial class VuserClass { private static int IMPORT_TIMEOUT = 300000; public int Action() { Sample.SampleDB.BeginOnlineLogin(); bool success = true; if (!Sample.SampleDB.IsSubscribed()) { subscribe(); lock (this) { lr.start_transaction("wait for import"); success = Monitor.Wait(this, IMPORT_TIMEOUT); if (success) { lr.end_transaction("wait for import", lr.AUTO); } else { lr.end_transaction("wait for import", lr.FAIL); } } } if (success) { query(); return 0; } else { return 1; } } //a transaction to register and begin sync public int subscribe() { //can be overrided by runtime setting in controller lr.think_time(1); lr.start_transaction("subscribe Application"); SampleDB.RegisterCallbackHandler(new PerfCallback(this)); Sample.SampleDB.Subscribe(); lr.end_transaction("subscribe Application", lr.AUTO); return 0; } public int query() { //can be overrided by runtime setting in controller lr.think_time(1); lr.start_transaction("FindAll"); Sybase.Collections.GenericList<Customer> cusList = Customer.FindAll(); lr.end_transaction("FindAll", lr.AUTO); if (cusList.Size() > 0) { return 0; } else { return 1; } } } public class PerfCallback: Sybase.Persistence.DefaultCallbackHandler, ICallbackHandler { private object obj; //obj: lock object to be notified public PerfCallback(object obj) { this.obj = obj; } override public void OnImportSuccess() { lock (obj) { Monitor.Pulse(obj); } } } }
The following is the example code for vuser_end.cs:
//--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : //--------------------------------------------- using Sample; using System; using System.IO; namespace Script { public partial class VuserClass { public int vuser_end() { lr.start_transaction("Unsubscribe Application"); SampleDB.Unsubscribe(); lr.end_transaction("Unsubscribe Application", lr.AUTO); lr.start_transaction("Deregister Application"); //unregister and disconnect. make it block, so that it won't interfere with DeleteDatabase app.UnregisterApplication(TIMEOUT); lr.end_transaction("Deregister Application", lr.AUTO); //Cleanup try { if (SampleDB.DatabaseExists()) { lr.start_transaction("DeleteDatabase"); SampleDB.DeleteDatabase(); lr.end_transaction("DeleteDatabase", lr.AUTO); } } catch { } //When debugging you might want to comment out this line to check MOCA log Directory.Delete(USER_DATA_DIRECTORY, true); return 0; } } }