Index: /trunk/src/VBox/Main/include/USBProxyService.h
===================================================================
--- /trunk/src/VBox/Main/include/USBProxyService.h	(revision 37616)
+++ /trunk/src/VBox/Main/include/USBProxyService.h	(revision 37617)
@@ -197,4 +197,11 @@
 #  endif
 
+#ifdef UNIT_TEST
+void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
+                      const char *pcszDevicesRoot, bool fDevicesAccessible,
+                      int rcMethodInitResult);
+void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot);
+#endif
+
 /**
  * The Linux hosted USB Proxy Service.
@@ -212,28 +219,5 @@
 
 #  ifdef UNIT_TEST
-    /* Functions for setting our unit test mock functions.  Not quite sure if
-     * it is good form to mix test and production code like this, but it seems
-     * cleaner to me than tying the unit test to implementation details of the
-     * class. */
-    /** Select which access methods will be available to the @a init method
-     * during unit testing, and (hack!) what return code it will see from
-     * the access method-specific initialisation. */
-    void testSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
-                       const char *pcszDevicesRoot, bool fDevicesAccessible,
-                       int rcMethodInitResult)
-    {
-        mpcszTestUsbfsRoot = pcszUsbfsRoot;
-        mfTestUsbfsAccessible = fUsbfsAccessible;
-        mpcszTestDevicesRoot = pcszDevicesRoot;
-        mfTestDevicesAccessible = fDevicesAccessible;
-        mrcTestMethodInitResult = rcMethodInitResult;
-    }
-    /** Specify the environment that the @a init method will see during unit
-     * testing. */
-    void testSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
-    {
-        mpcszTestEnvUsb = pcszEnvUsb;
-        mpcszTestEnvUsbRoot = pcszEnvUsbRoot;
-    }
+    /* Test getters for querying internal state.  This will go away. */
     bool testGetUsingUsbfs(void) { return mUsingUsbfsDevices; }
     const char *testGetDevicesRoot(void) { return mDevicesRoot.c_str(); }
@@ -271,20 +255,4 @@
     VBoxMainHotplugWaiter *mpWaiter;
 #  endif
-#  ifdef UNIT_TEST
-    /** The path we pretend the usbfs root is located at, or NULL. */
-    const char *mpcszTestUsbfsRoot;
-    /** Should usbfs be accessible to the current user? */
-    bool mfTestUsbfsAccessible;
-    /** The path we pretend the device node tree root is located at, or NULL. */
-    const char *mpcszTestDevicesRoot;
-    /** Should the device node tree be accessible to the current user? */
-    bool mfTestDevicesAccessible;
-    /** The result of the usbfs/inotify-specific init */
-    int mrcTestMethodInitResult;
-    /** The value of the VBOX_USB environment variable. */
-    const char *mpcszTestEnvUsb;
-    /** The value of the VBOX_USB_ROOT environment variable. */
-    const char *mpcszTestEnvUsbRoot;
-#  endif
 };
 # endif /* RT_OS_LINUX */
Index: /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp	(revision 37616)
+++ /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp	(revision 37617)
@@ -64,43 +64,83 @@
       mhWakeupPipeW(NIL_RTPIPE), mUsingUsbfsDevices(true /* see init */),
       mUdevPolls(0), mpWaiter(NULL)
+{
+    LogFlowThisFunc(("aHost=%p\n", aHost));
+}
+
 #ifdef UNIT_TEST
-      , mpcszTestUsbfsRoot(NULL), mfTestUsbfsAccessible(false),
-      mpcszTestDevicesRoot(NULL), mfTestDevicesAccessible(false),
-      mrcTestMethodInitResult(VINF_SUCCESS), mpcszTestEnvUsb(NULL),
-      mpcszTestEnvUsbRoot(NULL)
-#endif
-{
-    LogFlowThisFunc(("aHost=%p\n", aHost));
-}
-
-#ifdef UNIT_TEST
+#  ifdef UNIT_TEST
+    /** The path we pretend the usbfs root is located at, or NULL. */
+    const char *s_pcszTestUsbfsRoot;
+    /** Should usbfs be accessible to the current user? */
+    bool s_fTestUsbfsAccessible;
+    /** The path we pretend the device node tree root is located at, or NULL. */
+    const char *s_pcszTestDevicesRoot;
+    /** Should the device node tree be accessible to the current user? */
+    bool s_fTestDevicesAccessible;
+    /** The result of the usbfs/inotify-specific init */
+    int s_rcTestMethodInitResult;
+    /** The value of the VBOX_USB environment variable. */
+    const char *s_pcszTestEnvUsb;
+    /** The value of the VBOX_USB_ROOT environment variable. */
+    const char *s_pcszTestEnvUsbRoot;
+#  endif
+
+/** Select which access methods will be available to the @a init method
+ * during unit testing, and (hack!) what return code it will see from
+ * the access method-specific initialisation. */
+void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
+                      const char *pcszDevicesRoot, bool fDevicesAccessible,
+                      int rcMethodInitResult)
+{
+    s_pcszTestUsbfsRoot = pcszUsbfsRoot;
+    s_fTestUsbfsAccessible = fUsbfsAccessible;
+    s_pcszTestDevicesRoot = pcszDevicesRoot;
+    s_fTestDevicesAccessible = fDevicesAccessible;
+    s_rcTestMethodInitResult = rcMethodInitResult;
+}
+
+/** Specify the environment that the @a init method will see during unit
+ * testing. */
+void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)
+{
+    s_pcszTestEnvUsb = pcszEnvUsb;
+    s_pcszTestEnvUsbRoot = pcszEnvUsbRoot;
+}
+
 /* For testing we redefine anything that accesses the outside world to
  * return test values. */
 # define RTEnvGet(a) \
-    (  !RTStrCmp(a, "VBOX_USB") ? mpcszTestEnvUsb \
-     : !RTStrCmp(a, "VBOX_USB_ROOT") ? mpcszTestEnvUsbRoot \
+    (  !RTStrCmp(a, "VBOX_USB") ? s_pcszTestEnvUsb \
+     : !RTStrCmp(a, "VBOX_USB_ROOT") ? s_pcszTestEnvUsbRoot \
      : NULL)
 # define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
-    (   ((fUseNodes) && mfTestDevicesAccessible \
-                     && !RTStrCmp(pcszPath, mpcszTestDevicesRoot)) \
-     || (!(fUseNodes) && mfTestUsbfsAccessible \
-                      && !RTStrCmp(pcszPath, mpcszTestUsbfsRoot)))
+    (   ((fUseNodes) && s_fTestDevicesAccessible \
+                     && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \
+     || (!(fUseNodes) && s_fTestUsbfsAccessible \
+                      && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot)))
 # define RTDirExists(pcszDir) \
     (   (pcszDir) \
-     && (   !RTStrCmp(pcszDir, mpcszTestDevicesRoot) \
-         || !RTStrCmp(pcszDir, mpcszTestUsbfsRoot)))
+     && (   !RTStrCmp(pcszDir, s_pcszTestDevicesRoot) \
+         || !RTStrCmp(pcszDir, s_pcszTestUsbfsRoot)))
 # define RTFileExists(pcszFile) \
     (   (pcszFile) \
-     && mpcszTestUsbfsRoot \
-     && !RTStrNCmp(pcszFile, mpcszTestUsbfsRoot, strlen(mpcszTestUsbfsRoot)) \
-     && !RTStrCmp(pcszFile + strlen(mpcszTestUsbfsRoot), "/devices"))
+     && s_pcszTestUsbfsRoot \
+     && !RTStrNCmp(pcszFile, s_pcszTestUsbfsRoot, strlen(s_pcszTestUsbfsRoot)) \
+     && !RTStrCmp(pcszFile + strlen(s_pcszTestUsbfsRoot), "/devices"))
 #endif
 
 /**
- * Initializes the object (called right after construction).
- *
- * @returns S_OK on success and non-fatal failures, some COM error otherwise.
- */
-HRESULT USBProxyServiceLinux::init(void)
+ * Selects the access method that will be used to access USB devices based on
+ * what is available on the host and what if anything the user has specified
+ * in the environment.
+ * @returns iprt status value
+ * @param  pfUsingUsbfsDevices  on success this will be set to true if 
+ *                              the prefered access method is USBFS-like and to
+ *                              false if it is sysfs/device node-like
+ * @param  ppcszDevicesRoot     on success the root of the tree of USBFS-like
+ *                              device nodes will be stored here
+ */
+int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices,
+                              const char **ppcszDevicesRoot)
 {
     /*
@@ -160,10 +200,31 @@
     if (pcszUsbRoot)
     {
-        mUsingUsbfsDevices = fUsbfsChosen;
-        mDevicesRoot = pcszUsbRoot;
+        *pfUsingUsbfsDevices = fUsbfsChosen;
+        *ppcszDevicesRoot = pcszUsbRoot;
+        return VINF_SUCCESS;
+    }
+    /* else */
+    return   pcszUsbFromEnv ? VERR_NOT_FOUND
+           : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
+           : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
+           : VERR_NOT_FOUND;
+}
+
+/**
+ * Initializes the object (called right after construction).
+ *
+ * @returns S_OK on success and non-fatal failures, some COM error otherwise.
+ */
+HRESULT USBProxyServiceLinux::init(void)
+{
+    const char *pcszDevicesRoot;
+    int rc = USBProxyLinuxChooseMethod(&mUsingUsbfsDevices, &pcszDevicesRoot);
+    if (RT_SUCCESS(rc))
+    {
+        mDevicesRoot = pcszDevicesRoot;
 #ifndef UNIT_TEST /* Hack for now */
-        int rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
+        rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
 #else
-        int rc = mrcTestMethodInitResult;
+        rc = s_rcTestMethodInitResult;
 #endif
         /* For the day when we have VBoxSVC release logging... */
@@ -171,11 +232,6 @@
                                : "Failed to initialise host USB using %s\n",
                 mUsingUsbfsDevices ? "USBFS" : "sysfs"));
-        mLastError = rc;
-    }
-    else
-        mLastError =   pcszUsbFromEnv ? VERR_NOT_FOUND
-                     : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
-                     : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
-                     : VERR_NOT_FOUND;
+    }
+    mLastError = rc;
     return S_OK;
 }
Index: /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp	(revision 37616)
+++ /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp	(revision 37617)
@@ -134,7 +134,7 @@
     {
         USBProxyServiceLinux test(NULL);
-        test.testSetEnv(s_testEnvironment[i].pcszEnvUsb,
+        TestUSBSetEnv(s_testEnvironment[i].pcszEnvUsb,
                         s_testEnvironment[i].pcszEnvUsbRoot);
-        test.testSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
+        TestUSBSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
                            s_testEnvironment[i].fUsbfsAccessible,
                            s_testEnvironment[i].pcszDevicesRoot,
