package mobisocial.musubi.service; import mobisocial.musubi.encoding.ObjEncoder; import mobisocial.musubi.model.MApp; import mobisocial.musubi.model.MDevice; import mobisocial.musubi.model.MEncodedMessage; import mobisocial.musubi.model.MFeed; import mobisocial.musubi.model.MIdentity; import mobisocial.musubi.model.MObject; import mobisocial.musubi.model.helpers.DeviceManager; import mobisocial.musubi.objects.StatusObj; import mobisocial.musubi.service.MessageEncodeProcessor.ProcessorThread; import mobisocial.musubi.util.Util; import mobisocial.socialkit.Obj; import mobisocial.socialkit.obj.MemObj; import mobisocial.test.MockMusubiAppContext; import mobisocial.test.TestDatabase; import org.json.JSONObject; import android.content.Intent; import android.database.sqlite.SQLiteOpenHelper; import android.os.Message; import android.test.ServiceTestCase; public class EncodeDecodeTest extends ServiceTestCase<MusubiService> { static final String TAG = "EncodeDecodeTest"; MIdentity me; MDevice meDevice; MIdentity claimedFriend; MIdentity unclaimedFriend; MDevice amigoDevice; SQLiteOpenHelper dbh; TestDatabase database; MessageEncodeProcessor encoder; MessageDecodeProcessor decoder; ObjPipelineProcessor pipeline; MockMusubiAppContext context; public EncodeDecodeTest() { super(MusubiService.class); } @Override protected void setUp() throws Exception { context = new MockMusubiAppContext(getContext()); setApplication(context); setContext(context); super.setUp(); dbh = context.getDatabaseSource(); database = new TestDatabase(getContext(), dbh); me = database.insertIdentity(database.randomIBIdentity(), true, true); DeviceManager dm = new DeviceManager(dbh); meDevice = new MDevice(); meDevice.identityId_ = me.id_; meDevice.deviceName_ = dm.getLocalDeviceName(); dm.insertDevice(meDevice); claimedFriend = database.insertIdentity(database.randomIBIdentity(), false, true); unclaimedFriend = database.insertIdentity(database.randomIBIdentity(), false, false); encoder = MessageEncodeProcessor.newInstance(getContext(), dbh, null, context.getSettings().mAlternateIdentityProvider); decoder = MessageDecodeProcessor.newInstance(getContext(), dbh, null, context.getSettings().mAlternateIdentityProvider); pipeline = ObjPipelineProcessor.newInstance(getContext()); } public void tearDown() { if(getService() != null) getService().shutdownThreads(); dbh.close(); } public void testEncodeBasic() throws Exception { // Prepare a bit of data MessageEncodeProcessor encoder = MessageEncodeProcessor.newInstance(getContext(), dbh, null, context.getSettings().mAlternateIdentityProvider); MApp app = database.getAppManager().ensureApp(getContext().getPackageName()); MFeed feed = database.createFixedFeed(me, claimedFriend, unclaimedFriend); Obj obj1 = new MemObj("anon", null, null, null, "funny business"); MObject send1 = new MObject(); send1.appId_ = app.id_; send1.feedId_ = feed.id_; send1.identityId_ = me.id_; send1.deviceId_ = meDevice.id_; ObjEncoder.populate(send1, obj1); database.getObjectManager().insertObject(send1); Obj obj2 = new MemObj("status", new JSONObject("{\"text\":\"woaw\"}"), null, null, null); MObject send2 = new MObject(); send2.appId_ = app.id_; send2.feedId_ = feed.id_; send2.identityId_ = me.id_; send2.deviceId_ = meDevice.id_; ObjEncoder.populate(send2, obj2); database.getObjectManager().insertObject(send2); Obj obj3 = new MemObj("status", new JSONObject("{\"text\":\"seven\"}"), null, 7, null); MObject send3 = new MObject(); send3.appId_ = app.id_; send3.feedId_ = feed.id_; send3.identityId_ = me.id_; send3.deviceId_ = meDevice.id_; ObjEncoder.populate(send3, obj3); database.getObjectManager().insertObject(send3); // Pre-checks long[] idsToEncode = encoder.objectsToEncode(); assertEquals(3, idsToEncode.length); assertNull(send1.encodedId_); assertNull(send1.universalHash_); assertNull(send1.shortUniversalHash_); assertNull(send2.encodedId_); assertNull(send2.universalHash_); assertNull(send2.shortUniversalHash_); assertNotSame(send1.id_, send2.id_); long[] idsToProcess = pipeline.getUnprocessedObjs(); assertEquals(0, idsToProcess.length); // Run the actual encoder ProcessorThread proc = encoder.mProcessorThreads.get(0); for (long id : idsToEncode) { Message msg = proc.mHandler.obtainMessage(); msg.what = ProcessorThread.ENCODE_MESSAGE; msg.obj = id; proc.mHandler.handleMessage(msg); } idsToEncode = encoder.objectsToEncode(); assertEquals(0, idsToEncode.length); // Make sure things look good MObject encoded1 = database.getObjectManager().getObjectForId(send1.id_); MObject encoded2 = database.getObjectManager().getObjectForId(send2.id_); MObject encoded3 = database.getObjectManager().getObjectForId(send3.id_); MEncodedMessage msg3 = database.getEncodedMessageManager().lookupById(encoded3.encodedId_); assertEquals(send1.id_, encoded1.id_); assertEquals(send1.type_, encoded1.type_); assertEquals(encoded1.shortUniversalHash_, (Long)Util.shortHash(encoded1.universalHash_)); assertEquals(send2.id_, encoded2.id_); assertEquals(send2.type_, encoded2.type_); assertEquals(encoded2.shortUniversalHash_, (Long)Util.shortHash(encoded2.universalHash_)); assertNotNull(encoded1.encodedId_); assertNotNull(encoded2.encodedId_); assertTrue(msg3.outbound_); assertFalse(msg3.processed_); assertEquals(msg3.fromIdentityId_, (Long)me.id_); assertEquals(msg3.fromDevice_, (Long)meDevice.id_); long[] hopefullyEmpty = encoder.objectsToEncode(); assertEquals(0, hopefullyEmpty.length); hopefullyEmpty = decoder.objsToDecode().toArray(); assertEquals(0, hopefullyEmpty.length); // Make sure all objects will be processed idsToProcess = pipeline.getUnprocessedObjs(); assertEquals(3, idsToProcess.length); pipeline.onChange(false); idsToProcess = pipeline.getUnprocessedObjs(); assertEquals(0, idsToProcess.length); } public void testEncodeService() throws Exception { Intent startIntent = new Intent(); startIntent.setClass(getContext(), MusubiService.class); startService(startIntent); MApp app = database.getAppManager().ensureApp(getContext().getPackageName()); MFeed feed = database.createFixedFeed(me, claimedFriend, unclaimedFriend); // Send a renderable obj Obj obj1 = StatusObj.from("show me the renderable_"); MObject send1 = new MObject(); send1.appId_ = app.id_; send1.feedId_ = feed.id_; send1.identityId_ = me.id_; send1.deviceId_ = meDevice.id_; ObjEncoder.populate(send1, obj1); database.getObjectManager().insertObject(send1); MObject db1 = database.getObjectManager().getObjectForId(send1.id_); assertFalse(db1.renderable_); long[] idsToEncode = encoder.objectsToEncode(); assertEquals(idsToEncode.length, 1); long[] idsToProcess = pipeline.getUnprocessedObjs(); assertEquals(0, idsToProcess.length); // Trigger encoder and pipeline processors getContext().getContentResolver().notifyChange(MusubiService.PLAIN_OBJ_READY, null); try { for(int i = 0; i < 300; ++i) { if(encoder.objectsToEncode().length == 0 && pipeline.getUnprocessedObjs().length == 0) { break; } Thread.sleep(100); } } catch (InterruptedException e) {} // Verify idsToEncode = encoder.objectsToEncode(); assertEquals(0, idsToEncode.length); MObject proc1 = database.getObjectManager().getObjectForId(send1.id_); idsToProcess = pipeline.getUnprocessedObjs(); assertEquals(0, idsToProcess.length); assertTrue(proc1.renderable_); assertEquals((Long)Util.shortHash(proc1.universalHash_), proc1.shortUniversalHash_); } }