Backout 8ec01f6f316f (bug 705175), a1dc0efef542 (bug 716077), b5686f25b258 (bug 710445), 32f8d3be2ad1 (bug 715309) for mochitest/reftest failures on Android & Windows
authorEd Morley <bmo@edmorley.co.uk>
Sat, 07 Jan 2012 14:57:58 +0000
changeset 86450 879883efec3c4d6ac60a6d7e66b2c8576afc9aa0
parent 86449 48da43d7924abe0af693118478095db7b2861e31
child 86451 0d10b1ea459f1cc19a3f7db19090d4ec7db60415
push id674
push userffxbld
push dateTue, 13 Mar 2012 21:17:50 +0000
treeherdermozilla-beta@e3c4c92dec31 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs705175, 716077, 710445, 715309
milestone12.0a1
backs out8ec01f6f316f94544ed57caf1255df2e5c520015
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 8ec01f6f316f (bug 705175), a1dc0efef542 (bug 716077), b5686f25b258 (bug 710445), 32f8d3be2ad1 (bug 715309) for mochitest/reftest failures on Android & Windows
build/mobile/devicemanager.py
build/mobile/devicemanagerADB.py
build/mobile/devicemanagerSUT.py
build/mobile/remoteautomation.py
build/mobile/robocop/Assert.java.in
build/mobile/robocop/Driver.java.in
build/mobile/robocop/FennecNativeAssert.java.in
build/mobile/robocop/FennecNativeDriver.java.in
build/mobile/sutagent/android/DoCommand.java
mobile/android/base/tests/BaseTest.java.in
mobile/android/base/tests/testPan.java.in
testing/mochitest/runtestsremote.py
testing/testsuite-targets.mk
testing/xpcshell/remotexpcshelltests.py
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -203,24 +203,24 @@ class DeviceManager:
     #ex: '"name=value;name2=value2;etc=..." process args' -> 'process args'
     parts = appname.split('"')
     if (len(parts) > 2):
       appname = ' '.join(parts[2:]).strip()
   
     pieces = appname.split(' ')
     parts = pieces[0].split('/')
     app = parts[-1]
+    procre = re.compile('.*' + app + '.*')
 
     procList = self.getProcessList()
     if (procList == []):
       return None
       
     for proc in procList:
-      procName = proc[1].split('/')[-1]
-      if (procName == app):
+      if (procre.match(proc[1])):
         pid = proc[0]
         break
     return pid
 
   # external function
   # returns:
   #  success: output from testagent
   #  failure: None
@@ -341,17 +341,34 @@ class DeviceManager:
   # Either we will have /tests/fennec or /tests/firefox but we will never have
   # both.  Return the one that exists
   # TODO: ensure we can support org.mozilla.firefox
   # external function
   # returns:
   #  success: path for app root
   #  failure: None
   def getAppRoot(self):
-    assert 0 == 1
+    devroot = self.getDeviceRoot()
+    if (devroot == None):
+      return None
+
+    if (self.dirExists(devroot + '/fennec')):
+      return devroot + '/fennec'
+    elif (self.dirExists(devroot + '/firefox')):
+      return devroot + '/firefox'
+    elif (self.dirExsts('/data/data/org.mozilla.fennec')):
+      return 'org.mozilla.fennec'
+    elif (self.dirExists('/data/data/org.mozilla.firefox')):
+      return 'org.mozilla.firefox'
+    elif (self.dirExists('/data/data/org.mozilla.fennec_aurora')):
+      return 'org.mozilla.fennec_aurora'
+    elif (self.dirExists('/data/data/org.mozilla.firefox_beta')):
+      return 'org.mozilla.firefox_beta'
+
+    # Failure (either not installed or not a recognized platform)
     return None
 
   # Gets the directory location on the device for a specific test type
   # Type is one of: xpcshell|reftest|mochitest
   # external function
   # returns:
   #  success: path for test root
   #  failure: None
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -253,20 +253,16 @@ class DeviceManagerADB(DeviceManager):
       parts = parts[2:]
     return self.launchProcess(parts, failIfRunning)
 
   # external function
   # returns:
   #  success: output filename
   #  failure: None
   def launchProcess(self, cmd, outputFile = "process.txt", cwd = '', env = '', failIfRunning=False):
-    if cmd[0] == "am":
-      self.checkCmd(["shell"] + cmd)
-      return outputFile
-
     acmd = ["shell", "am","start"]
     cmd = ' '.join(cmd).strip()
     i = cmd.find(" ")
     # SUT identifies the URL by looking for :\\ -- another strategy to consider
     re_url = re.compile('^[http|file|chrome|about].*')
     last = cmd.rfind(" ")
     uri = ""
     args = ""
@@ -281,17 +277,17 @@ class DeviceManagerADB(DeviceManager):
     if args != "":
       acmd.append("args")
       acmd.append(args)
     if uri != "":
       acmd.append("-d")
       acmd.append(''.join(['\'',uri, '\'']));
     print acmd
     self.checkCmd(acmd)
-    return outputFile
+    return outputFile;
 
   # external function
   # returns:
   #  success: output from testagent
   #  failure: None
   def killProcess(self, appname):
     procs = self.getProcessList()
     for (pid, name, user) in procs:
@@ -421,24 +417,25 @@ class DeviceManagerADB(DeviceManager):
 
   # Either we will have /tests/fennec or /tests/firefox but we will never have
   # both.  Return the one that exists
   # TODO: ensure we can support org.mozilla.firefox
   # external function
   # returns:
   #  success: path for app root
   #  failure: None
-  def getAppRoot(self, packageName):
+  def getAppRoot(self):
     devroot = self.getDeviceRoot()
     if (devroot == None):
       return None
 
-    if (packageName and self.dirExists('/data/data/' + packageName)):
-      self.packageName = packageName
-      return '/data/data/' + packageName
+    if (self.dirExists(devroot + '/fennec')):
+      return devroot + '/fennec'
+    elif (self.dirExists(devroot + '/firefox')):
+      return devroot + '/firefox'
     elif (self.packageName and self.dirExists('/data/data/' + self.packageName)):
       return '/data/data/' + self.packageName
 
     # Failure (either not installed or not a recognized platform)
     print "devicemanagerADB: getAppRoot failed"
     return None
 
   # Gets the directory location on the device for a specific test type
--- a/build/mobile/devicemanagerSUT.py
+++ b/build/mobile/devicemanagerSUT.py
@@ -547,24 +547,24 @@ class DeviceManagerSUT(DeviceManager):
     #ex: '"name=value;name2=value2;etc=..." process args' -> 'process args'
     parts = appname.split('"')
     if (len(parts) > 2):
       appname = ' '.join(parts[2:]).strip()
   
     pieces = appname.split(' ')
     parts = pieces[0].split('/')
     app = parts[-1]
+    procre = re.compile('.*' + app + '.*')
 
     procList = self.getProcessList()
     if (procList == []):
       return None
       
     for proc in procList:
-      procName = proc[1].split('/')[-1]
-      if (procName == app):
+      if (procre.match(proc[1])):
         pid = proc[0]
         break
     return pid
 
   # external function
   # returns:
   #  success: output from testagent
   #  failure: None
@@ -853,25 +853,16 @@ class DeviceManagerSUT(DeviceManager):
     deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
 
     if (not self.dirExists(deviceRoot)):
       if (self.mkDir(deviceRoot) == None):
         return None
 
     return deviceRoot
 
-  def getAppRoot(self, packageName):
-    try:
-      data = self.verifySendCMD(['getapproot '+packageName])
-    except:
-      return None
-  
-    appRoot = self.stripPrompt(data).strip('\n')
-    return appRoot
-
   # external function
   # returns:
   #  success: output of unzip command
   #  failure: None
   def unpackFile(self, filename):
     devroot = self.getDeviceRoot()
     if (devroot == None):
       return None
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -117,21 +117,16 @@ class RemoteAutomation(Automation):
         except:
           print "WARNING: unable to remove directory: %s" % (dumpDir)
 
     def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
         # If remote profile is specified, use that instead
         if (self._remoteProfile):
             profileDir = self._remoteProfile
 
-        # Hack for robocop, if app & testURL == None and extraArgs contains the rest of the stuff, lets 
-        # assume extraArgs is all we need
-        if app == "am" and extraArgs[0] == "instrument":
-            return app, extraArgs
- 
         cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
         # Remove -foreground if it exists, if it doesn't this just returns
         try:
             args.remove('-foreground')
         except:
             pass
 #TODO: figure out which platform require NO_EM_RESTART
 #        return app, ['--environ:NO_EM_RESTART=1'] + args
--- a/build/mobile/robocop/Assert.java.in
+++ b/build/mobile/robocop/Assert.java.in
@@ -37,19 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 package @ANDROID_PACKAGE_NAME@;
 
 public interface Assert {
   void dumpLog(String message);
   void setLogFile(String filename);
-  void setTestName(String testName);
 
-  void finalize();
   void ok(boolean condition, String name, String diag);
   void is(Object a, Object b, String name);
   void isnot(Object a, Object b, String name);
   void todo(boolean condition, String name, String diag);
   void todo_is(Object a, Object b, String name);
   void todo_isnot(Object a, Object b, String name);
   void info(String name, String message);
 }
--- a/build/mobile/robocop/Driver.java.in
+++ b/build/mobile/robocop/Driver.java.in
@@ -63,9 +63,19 @@ public interface Driver {
   int getHeight();
   int getGeckoTop();
   int getGeckoLeft();
   int getGeckoWidth();
   int getGeckoHeight();
 
   void startFrameRecording();
   int stopFrameRecording();
+  void dumpLog(String message);
+  void setLogFile(String filename);
+
+  void ok(boolean condition, String name, String diag);
+  void is(Object a, Object b, String name);
+  void isnot(Object a, Object b, String name);
+  void todo(boolean condition, String name, String diag);
+  void todo_is(Object a, Object b, String name);
+  void todo_isnot(Object a, Object b, String name);
+  void info(String name, String message);
 }
--- a/build/mobile/robocop/FennecNativeAssert.java.in
+++ b/build/mobile/robocop/FennecNativeAssert.java.in
@@ -44,17 +44,16 @@ import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Date;
 
 import java.lang.Class;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.InvocationHandler;
 import java.lang.Long;
 
@@ -73,32 +72,17 @@ public class FennecNativeAssert implemen
   
   // Objects for reflexive access of fennec classes.
 
   private LinkedList<testInfo> testList = new LinkedList<testInfo>();
 
   // If waiting for an event.
   private boolean asleep = false;
 
-  // Internal state variables to make logging match up with existing mochitests
-  private int lineNumber = 0;
-  private int passed = 0;
-  private int failed = 0;
-  private int todo = 0;
-  
-  // Used to write the first line of the test file
-  private boolean logStarted = false;
-
-  // Used to write the test-start/test-end log lines
-  private String logTestName = "";
-
-  // Measure the time it takes to run test case
-  private long startTime = 0;
-
-  public FennecNativeAssert() {
+  public FennecNativeAssert(){
   }
 
   // Write information to a logfile and logcat
   public void dumpLog(String message)
   {
     File file = new File(logFile);
     BufferedWriter bw = null;
 
@@ -121,128 +105,66 @@ public class FennecNativeAssert implemen
 
     Log.i("Robocop", message);
   }
 
   // Set the filename used for dumpLog.
   public void setLogFile(String filename)
   {
     logFile = filename;
-
-    //TODO: these two messages are mochitest specific
-    String message;
-    if (!logStarted) {
-      message = Integer.toString(lineNumber++) + " INFO SimpleTest START";
-      dumpLog(message);
-      logStarted = true;
-    }
-
-    if (logTestName != "") {
-      message = Integer.toString(lineNumber++) + " INFO TEST-END | " + logTestName;
-      long diff = (new Date().getTime()) - startTime;
-      message += " | finished in " + diff + "ms";
-      dumpLog(message);
-      logTestName = "";
-    }
   }
 
-  public void setTestName(String testName)
-  {
-    String[] nameParts = testName.split("\\.");
-    logTestName = nameParts[nameParts.length - 1];
-    startTime = new Date().getTime();
-
-    //TODO: this is mochitest specific
-    String message = Integer.toString(lineNumber++) + " INFO TEST-START | " + logTestName;
-    dumpLog(message);
-  }
 
   class testInfo {
     public boolean result;
     public String name;
     public String diag;
     public boolean todo;
     public testInfo(boolean r, String n, String d, boolean t) {
       result = r;
       name = n;
       diag = d;
       todo = t;
     }
 
   }
 
-  private void _logMochitestResult(testInfo test, String passString, String failString)
+
+  private void _logResult(testInfo test, String passString, String failString)
   {
     boolean isError = true;
     String resultString = failString;
-    if (test.result || test.todo) {
+    if(test.result || test.todo){
       isError = false;
     }
-    if (test.result)
+    if(test.result)
     {
       resultString = passString;
     }
-    String diag = test.name;
-    if (test.diag != null) diag += " - " + test.diag;
+    String diag= test.name;
+    if(test.diag!=null) diag+= " - " + test.diag;
 
-    String message = Integer.toString(lineNumber++) + " INFO " + resultString + " | " + logTestName + " | " + diag;
-    if (isError) {
-      if (logFile == null)
+    String message = resultString + " | " + "ROBOCOP" + " | " + diag;
+    if(isError) {
+      if(logFile == null)
       {
         assert(false);
       }
       else {
         dumpLog(message);
       }
     }
     else {
       dumpLog(message);
     }
-
-    if (test.todo) {
-      todo++;
-    } else if (isError) {
-      failed++;
-    } else {
-      passed++;
-    }
-  }
-
-  public void finalize()
-  {
-    // It appears that we call finalize during cleanup, this might be an invalid assertion.
-    String message;
-
-    if (logTestName != "") {
-      long diff = (new Date().getTime()) - startTime;
-
-      //TODO: this is mochitest specific
-      message = Integer.toString(lineNumber++) + " INFO TEST-END | " + logTestName;
-      message += " | finished in " + diff + "ms";
-      dumpLog(message);
-
-      logTestName = "";
-    }
-
-    //TODO: this is all mochitest specific
-    message = Integer.toString(lineNumber++) + " INFO TEST-START | Shutdown";
-    dumpLog(message);
-    message = Integer.toString(lineNumber++) + " INFO Passed: " + Integer.toString(passed);
-    dumpLog(message);
-    message = Integer.toString(lineNumber++) + " INFO Failed: " + Integer.toString(failed);
-    dumpLog(message);
-    message = Integer.toString(lineNumber++) + " INFO Todo: " + Integer.toString(todo);
-    dumpLog(message);
-    message = Integer.toString(lineNumber++) + " INFO SimpleTest FINISHED";
-    dumpLog(message);
   }
 
   public void ok(boolean condition, String name, String diag) {
     testInfo test = new testInfo(condition, name, diag, false);
-    _logMochitestResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
+    _logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
     testList.add(test);
   }
 
   public void is(Object a, Object b, String name) {
     boolean pass = a.equals(b);
     String diag = "got " + a.toString() + ", expected " + b.toString();
     if(pass) {
       diag = a.toString() + " should equal " + b.toString();
@@ -256,17 +178,17 @@ public class FennecNativeAssert implemen
     if(pass) {
       diag = a.toString() + " should not equal " + b.toString();
     }
     ok(pass, name, diag);
   }
 
   public void todo(boolean condition, String name, String diag) {
     testInfo test = new testInfo(condition, name, diag, true);
-    _logMochitestResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
+    _logResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
     testList.add(test);
   }
 
   public void todo_is(Object a, Object b, String name) {
     boolean pass = a.equals(b);
     String diag = "got " + a.toString() + ", expected " + b.toString();
     if(pass) {
       diag = a.toString() + " should equal " + b.toString();
@@ -280,11 +202,11 @@ public class FennecNativeAssert implemen
     if(pass) {
       diag = a.toString() + " should not equal " + b.toString();
     }
     todo(pass, name, diag);
   }
 
   public void info(String name, String message) {
     testInfo test = new testInfo(true, name, message, false);
-    _logMochitestResult(test, "TEST-INFO", "INFO FAILED?");
+    _logResult(test, "TEST-INFO", "INFO FAILED?");
   }
 }
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -65,28 +65,32 @@ import org.json.*;
 
 import com.jayway.android.robotium.solo.Solo;
 
 public class FennecNativeDriver implements Driver {
   // Map of IDs to element names.
   private HashMap locators = null;
   private Activity activity;
   private Solo solo;
+  private String logFile;
 
   // Objects for reflexive access of fennec classes.
   private ClassLoader classLoader;
   private Class gel;
   private Class ge;
   private Class gas;
   private Method registerGEL;
   private Method unregisterGEL;
   private Method sendGE;
   private Method _startFrameRecording;
   private Method _stopFrameRecording;
 
+
+  private LinkedList<testInfo> testList = new LinkedList<testInfo>();
+
   public FennecNativeDriver(Activity activity, Solo robocop){
     this.activity = activity;
     this.solo = robocop;
 
     // Set up table of fennec_ids.
     locators = convertTextToTable(getFile("/mnt/sdcard/fennec_ids.txt"));
 
     // Set up reflexive access of java classes and methods.
@@ -277,21 +281,144 @@ public class FennecNativeDriver implemen
         text.append('\n');
       }
     } catch(IOException e) {
       e.printStackTrace();
     }
     return text.toString();  
   }
 
+  // Write information to a logfile and logcat
+  public void dumpLog(String message)
+  {
+    File file = new File(logFile);
+    BufferedWriter bw = null;
+
+    try {
+      bw = new BufferedWriter(new FileWriter(logFile, true));
+      bw.write(message);
+      bw.newLine();
+    } catch(IOException e) {
+      e.printStackTrace();
+    } finally {
+      try {
+        if (bw != null) {
+          bw.flush();
+          bw.close();
+        }
+      } catch (IOException ex) {
+        ex.printStackTrace();
+      }
+    }
+
+    Log.i("Robocop", message);
+  }
+
+  // Set the filename used for dumpLog.
+  public void setLogFile(String filename)
+  {
+    logFile = filename;
+  }
+
   // Takes a string of "key=value" pairs split by \n and creates a hash table.
   public static HashMap convertTextToTable(String data)
   {
     HashMap retVal = new HashMap();
 
     String[] lines = data.split("\n");
     for (int i = 0; i < lines.length; i++) {
       String[] parts = lines[i].split("=");
       retVal.put(parts[0].trim(), parts[1].trim());
     }
     return retVal;
   }
+
+  class testInfo {
+    public boolean result;
+    public String name;
+    public String diag;
+    public boolean todo;
+    public testInfo(boolean r, String n, String d, boolean t) {
+      result = r;
+      name = n;
+      diag = d;
+      todo = t;
+    }
+
+  }
+
+
+  private void _logResult(testInfo test, String passString, String failString)
+  {
+    boolean isError = true;
+    String resultString = failString;
+    if(test.result || test.todo){
+      isError = false;
+    }
+    if(test.result)
+    {
+      resultString = passString;
+    }
+    String diag= test.name;
+    if(test.diag!=null) diag+= " - " + test.diag;
+
+    String message = resultString + " | " + "ROBOCOP" + " | " + diag;
+    if(isError) {
+      dumpLog(message);
+    }
+    else {
+      dumpLog(message);
+    }
+  }
+
+  public void ok(boolean condition, String name, String diag) {
+    testInfo test = new testInfo(condition, name, diag, false);
+    _logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
+    testList.add(test);
+  }
+
+  public void is(Object a, Object b, String name) {
+    boolean pass = a.equals(b);
+    String diag = "got " + a.toString() + ", expected " + b.toString();
+    if(pass) {
+      diag = a.toString() + " should equal " + b.toString();
+    }
+    ok(pass, name, diag);
+  }
+  
+  public void isnot(Object a, Object b, String name) {
+    boolean pass = !a.equals(b);
+    String diag = "didn't expect " + a.toString() + ", but got it";
+    if(pass) {
+      diag = a.toString() + " should not equal " + b.toString();
+    }
+    ok(pass, name, diag);
+  }
+
+  public void todo(boolean condition, String name, String diag) {
+    testInfo test = new testInfo(condition, name, diag, true);
+    _logResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
+    testList.add(test);
+  }
+
+  public void todo_is(Object a, Object b, String name) {
+    boolean pass = a.equals(b);
+    String diag = "got " + a.toString() + ", expected " + b.toString();
+    if(pass) {
+      diag = a.toString() + " should equal " + b.toString();
+    }
+    todo(pass, name, diag);
+  }
+  
+  public void todo_isnot(Object a, Object b, String name) {
+    boolean pass = !a.equals(b);
+    String diag = "didn't expect " + a.toString() + ", but got it";
+    if(pass) {
+      diag = a.toString() + " should not equal " + b.toString();
+    }
+    todo(pass, name, diag);
+  }
+
+  public void info(String name, String message) {
+    testInfo test = new testInfo(true, name, message, false);
+    _logResult(test, "TEST-INFO", "INFO FAILED?");
+  }
 }
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -132,17 +132,17 @@ public class DoCommand {
 
     String    currentDir = "/";
     String    sErrorPrefix = "##AGENT-WARNING## ";
     boolean bTraceOn = false;
 
     String ffxProvider = "org.mozilla.ffxcp";
     String fenProvider = "org.mozilla.fencp";
 
-    private final String prgVersion = "SUTAgentAndroid Version 1.04";
+    private final String prgVersion = "SUTAgentAndroid Version 1.03";
 
     public enum Command
         {
         RUN ("run"),
         EXEC ("exec"),
         ENVRUN ("envrun"),
         KILL ("kill"),
         PS ("ps"),
@@ -1280,17 +1280,17 @@ private void CancelNotification()
         String sRet = sErrorPrefix + " internal error [no context]";
         Context ctx = contextWrapper.getApplicationContext();
 
         if (ctx != null)
             {
             try {
                 Context appCtx = ctx.createPackageContext(AppName, 0);
                 ContextWrapper appCtxW = new ContextWrapper(appCtx);
-                sRet = appCtxW.getApplicationInfo().dataDir;
+                sRet = appCtxW.getPackageResourcePath();
                 appCtxW = null;
                 appCtx = null;
                 ctx = null;
                 System.gc();
                 }
             catch (NameNotFoundException e)
                 {
                 e.printStackTrace();
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -46,26 +46,25 @@ abstract class BaseTest extends Activity
         // Start the activity
         setActivityIntent(i);
         mActivity = getActivity();
 
         // Set up Robotium.solo and Driver objects
         mSolo = new Solo(getInstrumentation());
         mDriver = new FennecNativeDriver(mActivity, mSolo);
         mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation());
+        mDriver.setLogFile((String)config.get("logfile"));
 
         mAsserter = new FennecNativeAssert();
         mAsserter.setLogFile((String)config.get("logfile"));
-        mAsserter.setTestName(this.getClass().getName());
     }
 
     @Override
     public void tearDown() throws Exception {
         try {
-            mAsserter.finalize();
             mSolo.finalize();
         } catch (Throwable e) {
             e.printStackTrace();
         }
         getActivity().finish();
         super.tearDown();
     }
 
--- a/mobile/android/base/tests/testPan.java.in
+++ b/mobile/android/base/tests/testPan.java.in
@@ -27,13 +27,13 @@ public class testPan extends BaseTest {
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             i++;
         } while (i < 1000 && mDriver.getScrollHeight() + 2 * mDriver.getHeight() < mDriver.getPageHeight());
         // asserter.ok(i < 1000, "Less than 1000", "Should take less than 1000 drags to get to bottom of the page.");
 
         int frames = mDriver.stopFrameRecording();
-        mAsserter.dumpLog("__start_report" + Integer.toString(frames) + "__end_report");
+        mDriver.dumpLog("__start_report" + Integer.toString(frames) + "__end_report");
         long msecs = System.currentTimeMillis();
-        mAsserter.dumpLog("__startTimestamp" + msecs + "__endTimestamp");
+        mDriver.dumpLog("__startTimestamp" + msecs + "__endTimestamp");
     }	
 }
--- a/testing/mochitest/runtestsremote.py
+++ b/testing/mochitest/runtestsremote.py
@@ -104,24 +104,19 @@ class RemoteOptions(MochitestOptions):
 
         self.add_option("--pidfile", action = "store",
                     type = "string", dest = "pidFile",
                     help = "name of the pidfile to generate")
         defaults["pidFile"] = ""
 
         self.add_option("--robocop", action = "store",
                     type = "string", dest = "robocop",
-                    help = "name of the .ini file containing the list of tests to run")
+                    help = "use when running robotium tests on native UI")
         defaults["robocop"] = ""
 
-        self.add_option("--robocop-path", action = "store",
-                    type = "string", dest = "robocopPath",
-                    help = "Path to the folder where robocop.apk is located at.  Primarily used for ADB test running")
-        defaults["robocopPath"] = ""
-
         defaults["remoteTestRoot"] = None
         defaults["logFile"] = "mochitest.log"
         defaults["autorun"] = True
         defaults["closeWhenDone"] = True
         defaults["testPath"] = ""
         defaults["app"] = None
 
         self.set_defaults(**defaults)
@@ -170,27 +165,16 @@ class RemoteOptions(MochitestOptions):
             else:
                 options.xrePath = options.utilityPath
 
         if (options.pidFile != ""):
             f = open(options.pidFile, 'w')
             f.write("%s" % os.getpid())
             f.close()
 
-        # Robocop specific options
-        if options.robocop and not os.path.exists(options.robocop):
-            print "ERROR: Unable to find specified manifest '%s'" % options.robocop
-            return None
-        options.robocop = os.path.abspath(options.robocop)
-
-        if options.robocopPath and not os.path.exists(os.path.join(options.robocopPath, 'robocop.apk')):
-            print "ERROR: Unable to find robocop.apk in path '%s'" % options.robocopPath
-            return None
-        options.robocopPath = os.path.abspath(options.robocopPath)
-
         return options
 
     def verifyOptions(self, options, mochitest):
         # since we are reusing verifyOptions, it will exit if App is not found
         temp = options.app
         options.app = sys.argv[0]
         tempPort = options.httpPort
         tempSSL = options.sslPort
@@ -202,17 +186,16 @@ class RemoteOptions(MochitestOptions):
         options.httpPort = tempPort
 
         return options 
 
 class MochiRemote(Mochitest):
 
     _automation = None
     _dm = None
-    localProfile = None
 
     def __init__(self, automation, devmgr, options):
         self._automation = automation
         Mochitest.__init__(self, self._automation)
         self._dm = devmgr
         self.runSSLTunnel = False
         self.remoteProfile = options.remoteTestRoot + "/profile"
         self._automation.setRemoteProfile(self.remoteProfile)
@@ -290,18 +273,16 @@ class MochiRemote(Mochitest):
         options.xrePath = remoteXrePath
         options.utilityPath = remoteUtilityPath
         options.profilePath = remoteProfilePath
          
     def stopWebServer(self, options):
         self.server.stop()
         
     def buildProfile(self, options):
-        if self.localProfile:
-            options.profilePath = self.localProfile
         manifest = Mochitest.buildProfile(self, options)
         self.localProfile = options.profilePath
         self._dm.removeDir(self.remoteProfile)
         if self._dm.pushDir(options.profilePath, self.remoteProfile) == None:
             raise devicemanager.FileError("Unable to copy profile to device.")
 
         options.profilePath = self.remoteProfile
         return manifest
@@ -333,17 +314,17 @@ class MochiRemote(Mochitest):
         return logFile
 
 def main():
     scriptdir = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
     dm_none = devicemanagerADB.DeviceManagerADB()
     auto = RemoteAutomation(dm_none, "fennec")
     parser = RemoteOptions(auto, scriptdir)
     options, args = parser.parse_args()
-    if (options.dm_trans == "adb"):
+    if (options.dm_trans == "adb" or options.robocop):
         if (options.deviceIP):
             dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort)
         else:
             dm = dm_none
     else:
          dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort)
     auto.setDeviceManager(dm)
     options = parser.verifyRemoteOptions(options, auto)
@@ -365,61 +346,55 @@ def main():
     
     logParent = os.path.dirname(options.remoteLogFile)
     dm.mkDir(logParent);
     auto.setRemoteLog(options.remoteLogFile)
     auto.setServerInfo(options.webServer, options.httpPort, options.sslPort)
 
     procName = options.app.split('/')[-1]
     if (dm.processExist(procName)):
-        dm.killProcess(procName)
+      dm.killProcess(procName)
     
     if (options.robocop):
-        mp = manifestparser.TestManifest(strict=False)
-        # TODO: pull this in dynamically
-        mp.read(options.robocop)
-        robocop_tests = mp.active_tests(exists=False)
-
-        fHandle = open("robotium.config", "w")
-        fHandle.write("profile=%s\n" % (mochitest.remoteProfile))
-        fHandle.write("logfile=%s\n" % (options.remoteLogFile))
-        fHandle.close()
-        deviceRoot = dm.getDeviceRoot()
-      
-        # Note, we are pushing to /sdcard since we have this location hard coded in robocop
-        dm.pushFile("robotium.config", "/sdcard/robotium.config")
-        dm.pushFile(os.path.abspath(options.robocop + "/fennec_ids.txt"), "/sdcard/fennec_ids.txt")
-        options.extraPrefs.append('robocop.logfile="%s/robocop.log"' % deviceRoot)
+      mp = manifestparser.TestManifest(strict=False)
+      # TODO: pull this in dynamically
+      mp.read('robocop.ini')
+      robocop_tests = mp.active_tests(exists=False)
 
-        if (options.dm_trans == 'adb' and options.robocopPath):
-          dm.checkCmd(["install", "-r", os.path.join(options.robocopPath, "robocop.apk")])
-
-        appname = options.app
-        for test in robocop_tests:
-            if options.testPath and options.testPath != test['name']:
-                continue
+      fHandle = open("robotium.config", "w")
+      fHandle.write("profile=%s\n" % (mochitest.remoteProfile))
+      fHandle.write("logfile=%s\n" % (options.remoteLogFile))
+      fHandle.close()
+      deviceRoot = dm.getDeviceRoot()
+      
+      # Note, we are pushing to /sdcard since we have this location hard coded in robocop
+      dm.pushFile("robotium.config", "/sdcard/robotium.config")
+      dm.pushFile(os.path.abspath(options.robocop + "/fennec_ids.txt"), "/sdcard/fennec_ids.txt")
+      options.extraPrefs.append('robocop.logfile="%s/robocop.log"' % deviceRoot)
 
-            options.app = "am"
-            options.browserArgs = ["instrument", "-w", "-e", "class"]
-            options.browserArgs.append("%s.tests.%s" % (appname, test['name']))
-            options.browserArgs.append("org.mozilla.roboexample.test/android.test.InstrumentationTestRunner")
+      manifest = mochitest.buildProfile(options)
+      mochitest.startWebServer(options)
 
-            try:
-                retVal = mochitest.runTests(options)
-            except:
-                print "TEST-UNEXPECTED-ERROR | %s | Exception caught while running robocop tests." % sys.exc_info()[1]
-                mochitest.stopWebServer(options)
-                mochitest.stopWebSocketServer(options)
-                sys.exit(1)
+      if (options.dm_trans == 'adb'):
+        dm.checkCmd(["install", "-r", os.path.join(options.robocop, "robocop.apk")])
+        for test in robocop_tests:
+          cmd = ["shell", "am", "instrument", "-w", "-e", "class"]
+          cmd.append("%s.tests.%s" % (options.app, test['name']))
+          cmd.append("org.mozilla.roboexample.test/android.test.InstrumentationTestRunner")
+          retVal = dm.checkCmd(cmd)
+      else:
+        # SUTAgent needs to install robocop and not crash when we launch robocop.
+        retVal = dm.launchProcess(["am", "instrument", "-w", "org.mozilla.roboexample.test/android.test.InstrumentationTestRunner"])
+      mochitest.stopWebServer(options)
     else:
       try:
         retVal = mochitest.runTests(options)
       except:
         print "TEST-UNEXPECTED-ERROR | | Exception caught while running tests."
         mochitest.stopWebServer(options)
         mochitest.stopWebSocketServer(options)
         sys.exit(1)
-
+      
     sys.exit(retVal)
         
 if __name__ == "__main__":
     main()
 
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -71,20 +71,20 @@ RUN_MOCHITEST_REMOTE = \
 	rm -f ./$@.log && \
 	$(PYTHON) _tests/testing/mochitest/runtestsremote.py --autorun --close-when-done \
 	  --console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=$(DM_TRANS) \
 	  --app=$(TEST_PACKAGE_NAME) --deviceIP=${TEST_DEVICE} --xre-path=${MOZ_HOST_BIN} \
 	  $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 RUN_MOCHITEST_ROBOTIUM = \
   rm -f ./$@.log && \
-  $(PYTHON) _tests/testing/mochitest/runtestsremote.py --robocop-path build/mobile/robocop \
+  $(PYTHON) _tests/testing/mochitest/runtestsremote.py --robocop ../../../build/mobile/robocop \
     --console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=adb \
     --app=$(TEST_PACKAGE_NAME) --deviceIP=${TEST_DEVICE} --xre-path=${MOZ_HOST_BIN} \
-    --robocop build/mobile/robocop/robocop.ini $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
+    $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS)
 
 ifndef NO_FAIL_ON_TEST_ERRORS
 define CHECK_TEST_ERROR
   @errors=`grep "TEST-UNEXPECTED-" $@.log` ;\
   if test "$$errors" ; then \
 	  echo "$@ failed:"; \
 	  echo "$$errors"; \
 	  exit 1; \
--- a/testing/xpcshell/remotexpcshelltests.py
+++ b/testing/xpcshell/remotexpcshelltests.py
@@ -32,17 +32,16 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK ***** */
 
 import re, sys, os
-import subprocess
 import runxpcshelltests as xpcshell
 from automationutils import *
 import devicemanager, devicemanagerADB, devicemanagerSUT
 
 # A specialization of XPCShellTests that runs tests on an Android device
 # via devicemanager.
 class XPCShellRemote(xpcshell.XPCShellTests, object):
 
@@ -62,32 +61,16 @@ class XPCShellRemote(xpcshell.XPCShellTe
         self.remoteComponentsDir = self.remoteJoin(self.remoteTestRoot, "c")
         self.profileDir = self.remoteJoin(self.remoteTestRoot, "p")
         if options.setup:
           self.setupUtilities()
           self.setupTestDir()
         self.remoteAPK = self.remoteJoin(self.remoteBinDir, os.path.basename(options.localAPK))
         self.remoteDebugger = options.debugger
         self.remoteDebuggerArgs = options.debuggerArgs  
-        self.setAppRoot()
-
-    def setAppRoot(self):
-        # Determine the application root directory associated with the package 
-        # name used by the Fennec APK.
-        self.appRoot = None
-        packageName = None
-        if self.options.localAPK:
-          try:
-            packageName = subprocess.check_output(["unzip", "-p", self.options.localAPK, "package-name.txt"])
-            if packageName:
-              self.appRoot = self.device.getAppRoot(packageName.strip())
-          except Exception as detail:
-            print "unable to determine app root: " + detail
-            pass
-        return None
 
     def remoteJoin(self, path1, path2):
         joined = os.path.join(path1, path2)
         joined = joined.replace('\\', '/')
         return joined
 
     def remoteForLocal(self, local):
         for mapping in self.pathMapping:
@@ -215,19 +198,19 @@ class XPCShellRemote(xpcshell.XPCShellTe
             cmd[index] = part
           index = index + 1
 
         xpcshell = self.remoteJoin(self.remoteBinDir, "xpcshell")
 
         shellArgs = "cd "+self.remoteHere
         shellArgs += "; LD_LIBRARY_PATH="+self.remoteBinDir
         shellArgs += "; export CACHE_PATH="+self.remoteBinDir
-        if (self.appRoot):
+        if (self.device.getAppRoot()):
           # xpcshell still runs without GRE_HOME; it may not be necessary
-          shellArgs += "; export GRE_HOME="+self.appRoot
+          shellArgs += "; export GRE_HOME="+self.device.getAppRoot()
         shellArgs += "; export XPCSHELL_TEST_PROFILE_DIR="+self.profileDir
         shellArgs += "; "+xpcshell+" "
         shellArgs += " ".join(cmd[1:])
 
         if self.verbose:
           self.log.info(shellArgs)
 
         # If the adb version of devicemanager is used and the arguments passed