Index: /trunk/src/VBox/Main/include/USBGetDevices.h
===================================================================
--- /trunk/src/VBox/Main/include/USBGetDevices.h	(revision 36992)
+++ /trunk/src/VBox/Main/include/USBGetDevices.h	(revision 36993)
@@ -84,4 +84,21 @@
                                          bool fIsDeviceNodes);
 
+#ifdef UNIT_TEST
+/**
+ * Specify the list of devices that will appear to be available through
+ * usbfs during unit testing (of USBProxyLinuxGetDevices)
+ * @param  pacszDeviceAddresses  NULL terminated array of usbfs device addresses
+ */
+extern void TestUSBSetAvailableUsbfsDevices(const char **pacszDeviceAddresses);
+/**
+ * Specify the list of files that access will report as accessible (at present
+ * we only do accessible or not accessible) during unit testing (of
+ * USBProxyLinuxGetDevices)
+ * @param  pacszAccessibleFiles  NULL terminated array of file paths to be
+ *                               reported accessible
+ */
+extern void TestUSBSetAccessibleFiles(const char **pacszAccessibleFiles);
+#endif
+
 /**
  * Get the list of USB devices supported by the system.  Should be freed using
Index: /trunk/src/VBox/Main/include/USBProxyService.h
===================================================================
--- /trunk/src/VBox/Main/include/USBProxyService.h	(revision 36992)
+++ /trunk/src/VBox/Main/include/USBProxyService.h	(revision 36993)
@@ -211,12 +211,35 @@
     virtual int releaseDevice(HostUSBDevice *aDevice);
 
-protected:
-#ifdef TESTCASE
-    virtual
-#endif
+#  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;
+    }
+    bool testGetUsingUsbfs(void) { return mUsingUsbfsDevices; }
+    const char *testGetDevicesRoot(void) { return mDevicesRoot.c_str(); }
+#  endif
+
+protected:
     int initUsbfs(void);
-#ifdef TESTCASE
-    virtual
-#endif
     int initSysfs(void);
     void doUsbfsCleanupAsNeeded(void);
@@ -248,4 +271,20 @@
     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/USBProxyService.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/USBProxyService.cpp	(revision 36992)
+++ /trunk/src/VBox/Main/src-server/USBProxyService.cpp	(revision 36993)
@@ -25,4 +25,5 @@
 #include "Logging.h"
 
+#include <VBox/com/array.h>
 #include <VBox/err.h>
 #include <iprt/asm.h>
Index: /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp	(revision 36992)
+++ /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp	(revision 36993)
@@ -1390,4 +1390,32 @@
 }
 
+#ifdef UNIT_TEST
+/* Set up mock functions for USBProxyLinuxCheckDeviceRoot - here dlsym and close
+ * for the inotify presence check. */
+static int testInotifyInitGood(void) { return 0; }
+static int testInotifyInitBad(void) { return -1; }
+static bool s_fHaveInotifyLibC = true;
+static bool s_fHaveInotifyKernel = true;
+
+static void *testDLSym(void *handle, const char *symbol)
+{
+    Assert(handle == RTLD_DEFAULT);
+    Assert(!RTStrCmp(symbol, "inotify_init"));
+    if (!s_fHaveInotifyLibC)
+        return NULL;
+    if (s_fHaveInotifyKernel)
+        return (void *)testInotifyInitGood;
+    return (void *)testInotifyInitBad;
+}
+
+void TestUSBSetInotifyAvailable(bool fHaveInotifyLibC, bool fHaveInotifyKernel)
+{
+    s_fHaveInotifyLibC = fHaveInotifyLibC;
+    s_fHaveInotifyKernel = fHaveInotifyKernel;
+}
+# define dlsym testDLSym
+# define close(a) do {} while(0)
+#endif
+
 /** Is inotify available and working on this system?  This is a requirement
  * for using USB with sysfs */
@@ -1406,4 +1434,62 @@
 }
 
+#ifdef UNIT_TEST
+# undef dlsym
+# undef close
+#endif
+
+#ifdef UNIT_TEST
+/** Unit test list of usbfs addresses of connected devices. */
+static const char **s_pacszUsbfsDeviceAddresses = NULL;
+
+static PUSBDEVICE testGetUsbfsDevices(const char *pcszUsbfsRoot, bool testfs)
+{
+    const char **pcsz;
+    PUSBDEVICE pList = NULL, pTail = NULL;
+    for (pcsz = s_pacszUsbfsDeviceAddresses; pcsz && *pcsz; ++pcsz)
+    {
+        PUSBDEVICE pNext = (PUSBDEVICE)RTMemAllocZ(sizeof(USBDEVICE));
+        if (pNext)
+            pNext->pszAddress = RTStrDup(*pcsz);
+        if (!pNext || !pNext->pszAddress)
+        {
+            deviceListFree(&pList);
+            return NULL;
+        }
+        if (pTail)
+            pTail->pNext = pNext;
+        else
+            pList = pNext;
+        pTail = pNext;
+    }
+    return pList;
+}
+# define getDevicesFromUsbfs testGetUsbfsDevices
+
+void TestUSBSetAvailableUsbfsDevices(const char **pacszDeviceAddresses)
+{
+    s_pacszUsbfsDeviceAddresses = pacszDeviceAddresses;
+}
+
+/** Unit test list of files reported as accessible by access(3).  We only do
+ * accessible or not accessible. */
+static const char **s_pacszAccessibleFiles = NULL;
+
+static int testAccess(const char *pcszPath, int mode)
+{
+    const char **pcsz;
+    for (pcsz = s_pacszAccessibleFiles; pcsz && *pcsz; ++pcsz)
+        if (!RTStrCmp(pcszPath, *pcsz))
+            return 0;
+    return -1;
+}
+# define access testAccess
+
+void TestUSBSetAccessibleFiles(const char **pacszAccessibleFiles)
+{
+    s_pacszAccessibleFiles = pacszAccessibleFiles;
+}
+#endif
+
 bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes)
 {
@@ -1431,4 +1517,8 @@
 }
 
+#ifdef UNIT_TEST
+# undef getDevicesFromUsbfs
+# undef access
+#endif
 
 PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot,
Index: /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp	(revision 36992)
+++ /trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp	(revision 36993)
@@ -63,8 +63,36 @@
       mWakeupPipeW(NIL_RTFILE), mUsingUsbfsDevices(true /* see init */),
       mUdevPolls(0), mpWaiter(NULL)
+#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
+/* 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 \
+     : NULL)
+# define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
+    (   ((fUseNodes) && mfTestDevicesAccessible \
+                     && !RTStrCmp(pcszPath, mpcszTestDevicesRoot)) \
+     || (!(fUseNodes) && mfTestUsbfsAccessible \
+                      && !RTStrCmp(pcszPath, mpcszTestUsbfsRoot)))
+# define RTDirExists(pcszDir) \
+    (   (pcszDir) \
+     && (   !RTStrCmp(pcszDir, mpcszTestDevicesRoot) \
+         || !RTStrCmp(pcszDir, mpcszTestUsbfsRoot)))
+# define RTFileExists(pcszFile) \
+    (   (pcszFile) \
+     && mpcszTestUsbfsRoot \
+     && !RTStrNCmp(pcszFile, mpcszTestUsbfsRoot, strlen(mpcszTestUsbfsRoot)) \
+     && !RTStrCmp(pcszFile + strlen(mpcszTestUsbfsRoot), "/devices"))
+#endif
 
 /**
@@ -131,5 +159,9 @@
         mUsingUsbfsDevices = !fUseSysfs;
         mDevicesRoot = pcszUsbRoot;
+#ifndef UNIT_TEST /* Hack for now */
         int rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
+#else
+        int rc = mrcTestMethodInitResult;
+#endif
         /* For the day when we have VBoxSVC release logging... */
         LogRel((RT_SUCCESS(rc) ? "Successfully initialised host USB using %s\n"
@@ -145,4 +177,10 @@
 }
 
+#ifdef UNIT_TEST
+# undef RTEnvGet
+# undef USBProxyLinuxCheckDeviceRoot
+# undef RTDirExists
+# undef RTFileExists
+#endif
 
 /**
Index: /trunk/src/VBox/Main/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/testcase/Makefile.kmk	(revision 36992)
+++ /trunk/src/VBox/Main/testcase/Makefile.kmk	(revision 36993)
@@ -172,5 +172,6 @@
 tstUSBProxyLinux_SOURCES   = \
 	tstUSBProxyLinux.cpp \
-	../src-server/linux/USBProxyServiceLinux.cpp
+	../src-server/linux/USBProxyServiceLinux.cpp \
+	../src-server/linux/USBGetDevices.cpp
 tstUSBProxyLinux_INCS      = \
 	. \
@@ -180,10 +181,12 @@
 	$(VBOX_PATH_SDK)/bindings/xpcom/include/xpcom
 tstUSBProxyLinux_DEFS      = \
-	TESTCASE \
+	UNIT_TEST \
+	VBOX_WITH_USB \
 	VBOX_USB_WITH_SYSFS \
-	VBOX_WITH_SYSFS_BY_DEFAULT \
 	VBOX_WITH_XPCOM
 tstUSBProxyLinux_DEPS     = \
 	$(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
+tstUSBProxyLinux_LIBS     += \
+	$(PATH_OUT)/lib/USBLib.a
 
 
Index: /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp	(revision 36992)
+++ /trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp	(revision 36993)
@@ -23,7 +23,8 @@
 #include "USBGetDevices.h"
 
+#include <VBox/err.h>
 #include <iprt/assert.h>
-#include <iprt/err.h>
 #include <iprt/env.h>
+#include <iprt/string.h>
 #include <iprt/test.h>
 
@@ -62,108 +63,116 @@
 }
 
-static const char *s_pcszDeviceRoot = "";
-static bool s_fIsDeviceNodes = false;
-
-bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot,
-                                  bool fIsDeviceNodes)
-{
-    return (   (!strcmp(s_pcszDeviceRoot, pcszRoot))
-            && (s_fIsDeviceNodes == fIsDeviceNodes));
-}
-
-static struct
-{
+int USBProxyService::getLastError(void)
+{
+    return mLastError;
+}
+
+void SysFreeString(BSTR bstr)
+{
+    Assert(0);
+}
+
+static struct 
+{
+    const char *pcszEnvUsb;
+    const char *pcszEnvUsbRoot;
     const char *pcszDevicesRoot;
-    bool fUseSysfs;
-} s_getDevices;
-
-PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot,
-                                   bool fUseSysfs)
-{
-    s_getDevices.pcszDevicesRoot = pcszDevicesRoot;
-    s_getDevices.fUseSysfs = fUseSysfs;
-    return NULL;
-}
-
-void SysFreeString(BSTR bstr)
-{
-    Assert(0);
-}
-
-/*** END STUBS ***/
-
-class tstUSBProxyLinux : public USBProxyServiceLinux
-{
-protected:
-    virtual int initUsbfs(void) { return VINF_SUCCESS; }
-    virtual int initSysfs(void) { return VINF_SUCCESS; }
-public:
-    tstUSBProxyLinux(void) : USBProxyServiceLinux(NULL) {}
-    PUSBDEVICE getDevices(void)
-    {
-        return USBProxyServiceLinux::getDevices();
-    }
+    bool fDevicesAccessible;
+    const char *pcszUsbfsRoot;
+    bool fUsbfsAccessible;
+    int rcMethodInit;
+    int rcExpected;
+    const char *pcszDevicesRootExpected;
+    bool fUsingUsbfsExpected;
+} s_testEnvironment[] =
+{
+    { "sysfs", "/dev/bus/usb", NULL, false, NULL, false, VINF_SUCCESS, VINF_SUCCESS, "/dev/bus/usb", false },
+    { "sysfs", "/dev/bus/usb", NULL, false, NULL, false, VERR_NO_MEMORY, VERR_NO_MEMORY, "/dev/bus/usb", false },
+    { "sysfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VINF_SUCCESS, VINF_SUCCESS, "/dev/bus/usb", false },
+    { "sysfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VERR_NO_MEMORY, VERR_NO_MEMORY, "/dev/bus/usb", false },
+    { "sysfs", NULL, "/dev/usbvbox", true, NULL, false, VINF_SUCCESS, VINF_SUCCESS, "/dev/vboxusb", false },
+    { "usbfs", "/dev/bus/usb", NULL, false, NULL, false, VINF_SUCCESS, VINF_SUCCESS, "/dev/bus/usb", true },
+    { "usbfs", "/dev/bus/usb", NULL, false, NULL, false, VERR_NO_MEMORY, VERR_NO_MEMORY, "/dev/bus/usb", true },
+    { "usbfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VINF_SUCCESS, VINF_SUCCESS, "/dev/bus/usb", true },
+    { "usbfs", "/dev/bus/usb", "/dev/usbvbox", false, "/proc/usb/bus", false, VERR_NO_MEMORY, VERR_NO_MEMORY, "/dev/bus/usb", true },
+    { "usbfs", NULL, NULL, false, "/proc/bus/usb", true, VINF_SUCCESS, VINF_SUCCESS, "/proc/bus/usb", true },
+    { NULL, NULL, "/dev/vboxusb", false, "/proc/bus/usb", false, VERR_NO_MEMORY, VERR_VUSB_USB_DEVICE_PERMISSION, "", true },
+    { NULL, NULL, "/dev/vboxusb", true, "/proc/bus/usb", false, VERR_NO_MEMORY, VERR_NO_MEMORY, "/dev/vboxusb", false },
+    { NULL, NULL, NULL, false, "/proc/bus/usb", false, VERR_NO_MEMORY, VERR_VUSB_USBFS_PERMISSION, "", true },
+    { NULL, NULL, NULL, false, "/proc/bus/usb", true, VERR_NO_MEMORY, VERR_NO_MEMORY, "/proc/bus/usb", true }
 };
 
-static struct 
-{
-    const char *pcszVBOX_USB;
-    const char *pcszVBOX_USB_ROOT;
-    const char *pcszReturnedRoot;
-    bool fReturnedUseSysfs;
-    bool fRequestedUseSysfs;
-    const char *pcszFinalRoot;
-    bool fFinalUseSysfs;
-} s_testEnvironment[] =
-{
-    { "sysfs", "/dev/bus/usb", "/proc/bus/usb", false, true, "/dev/bus/usb", true },
-    { "sysfs", "/dev/bus/usb", "/dev/vboxusb", true, true, "/dev/bus/usb", true },
-    { "sysfs", NULL, "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { "sysfs", NULL, "/dev/vboxusb", true, true, "/dev/vboxusb", true },
-    { "usbfs", "/dev/bus/usb", "/proc/bus/usb", false, false, "/dev/bus/usb", false },
-    { "usbfs", "/dev/bus/usb", "/dev/vboxusb", true, false, "/dev/bus/usb", false },
-    { "usbfs", NULL, "/proc/bus/usb", false, false, "/proc/bus/usb", false },
-    { "usbfs", NULL, "/dev/vboxusb", true, false, "/dev/vboxusb", true },
-    { "nofs", "/dev/bus/usb", "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { "nofs", "/dev/bus/usb", "/dev/vboxusb", true, true, "/dev/vboxusb", true },
-    { "nofs", NULL, "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { "nofs", NULL, "/dev/vboxusb", true, true, "/dev/vboxusb", true },
-    { "", "/dev/bus/usb", "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { "", "/dev/bus/usb", "/dev/vboxusb", true, true, "/dev/vboxusb", true },
-    { "", NULL, "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { "", NULL, "/dev/vboxusb", true, true, "/dev/vboxusb", true },
-    { NULL, "/dev/bus/usb", "/proc/bus/usb", false, true, "/proc/bus/usb", false },
-    { NULL, "/dev/bus/usb", "/dev/vboxusb", true, true, "/dev/vboxusb", true }
-};
-
-/** @note Fiddling with the real environment for this is not nice, in my
- * opinion at least. */
-static void testEnvironment(RTTEST hTest)
-{
-    RTTestSub(hTest, "Testing environment variable handling");
+static void testInit(RTTEST hTest)
+{
+    RTTestSub(hTest, "Testing USBProxyServiceLinux initialisation");
     for (unsigned i = 0; i < RT_ELEMENTS(s_testEnvironment); ++i)
     {
-        tstUSBProxyLinux test;
-        if (s_testEnvironment[i].pcszVBOX_USB)
-            RTEnvSet("VBOX_USB", s_testEnvironment[i].pcszVBOX_USB);
-        else
-            RTEnvUnset("VBOX_USB");
-        if (s_testEnvironment[i].pcszVBOX_USB_ROOT)
-            RTEnvSet("VBOX_USB_ROOT",
-                     s_testEnvironment[i].pcszVBOX_USB_ROOT);
-        else
-            RTEnvUnset("VBOX_USB_ROOT");
-        s_pcszDeviceRoot = s_testEnvironment[i].pcszReturnedRoot;
-        s_fIsDeviceNodes = s_testEnvironment[i].fReturnedUseSysfs;
-        RTTESTI_CHECK(test.init() == S_OK);
-        test.getDevices();
-        RTTESTI_CHECK_MSG(!strcmp(s_getDevices.pcszDevicesRoot,
-                          s_testEnvironment[i].pcszFinalRoot),
-                          ("i=%u: %s, %s\n", i, s_getDevices.pcszDevicesRoot,
-                          s_testEnvironment[i].pcszFinalRoot));
-        RTTESTI_CHECK_MSG(   s_getDevices.fUseSysfs
-                          == s_testEnvironment[i].fFinalUseSysfs,
-                          ("i=%u, %d, %d\n", i, s_getDevices.fUseSysfs,
-                          s_testEnvironment[i].fFinalUseSysfs));
+        USBProxyServiceLinux test(NULL);
+        test.testSetEnv(s_testEnvironment[i].pcszEnvUsb,
+                        s_testEnvironment[i].pcszEnvUsbRoot);
+        test.testSetupInit(s_testEnvironment[i].pcszUsbfsRoot,
+                           s_testEnvironment[i].fUsbfsAccessible,
+                           s_testEnvironment[i].pcszDevicesRoot,
+                           s_testEnvironment[i].fDevicesAccessible,
+                           s_testEnvironment[i].rcMethodInit);
+        HRESULT hrc = test.init();
+        RTTESTI_CHECK_MSG(hrc == S_OK,
+                           ("init() returned 0x%x on line %i!\n", hrc, i));
+        int rc = test.getLastError();
+        RTTESTI_CHECK_MSG(rc == s_testEnvironment[i].rcExpected,
+                          ("getLastError() returned %Rrc on line %i instead of %Rrc!\n",
+                           rc, i, s_testEnvironment[i].rcExpected));
+        const char *pcszDevicesRoot = test.testGetDevicesRoot();
+        RTTESTI_CHECK_MSG(!RTStrCmp(pcszDevicesRoot,
+                               s_testEnvironment[i].pcszDevicesRootExpected),
+                          ("testGetDevicesRoot() returned %s on line %i instead of %s!\n",
+                           pcszDevicesRoot, i,
+                           s_testEnvironment[i].pcszDevicesRootExpected));
+        bool fUsingUsbfs = test.testGetUsingUsbfs();
+        RTTESTI_CHECK_MSG(   fUsingUsbfs
+                          == s_testEnvironment[i].fUsingUsbfsExpected,
+                          ("testGetUsingUsbfs() returned %RTbool on line %i instead of %RTbool!\n",
+                           fUsingUsbfs, i,
+                           s_testEnvironment[i].fUsingUsbfsExpected));
+    }
+}
+
+static struct 
+{
+    const char *pacszDeviceAddresses[16];
+    const char *pacszAccessibleFiles[16];
+    const char *pcszRoot;
+    bool fIsDeviceNodes;
+    bool fAvailableExpected;
+} s_testCheckDeviceRoot[] =
+{
+    { { NULL }, { "/dev/vboxusb" }, "/dev/vboxusb", true, true },
+    { { NULL }, { NULL }, "/dev/vboxusb", true, false },
+    { { NULL }, { NULL }, "/proc/bus/usb", false, true },
+    { { "/proc/bus/usb/001/001" }, { NULL }, "/proc/bus/usb", false, false },
+    { { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
+      { "/proc/bus/usb/001/001" }, "/proc/bus/usb", false, false },
+    { { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
+      { "/proc/bus/usb/001/001", "/proc/bus/usb/002/002" },
+      "/proc/bus/usb", false, true }
+};
+
+static void testCheckDeviceRoot(RTTEST hTest)
+{
+    RTTestSub(hTest, "Testing the USBProxyLinuxCheckDeviceRoot API");
+    for (unsigned i = 0; i < RT_ELEMENTS(s_testCheckDeviceRoot); ++i)
+    {
+        TestUSBSetAvailableUsbfsDevices(s_testCheckDeviceRoot[i]
+                                                .pacszDeviceAddresses);
+        TestUSBSetAccessibleFiles(s_testCheckDeviceRoot[i]
+                                                .pacszAccessibleFiles);
+        bool fAvailable = USBProxyLinuxCheckDeviceRoot
+                                  (s_testCheckDeviceRoot[i].pcszRoot,
+                                   s_testCheckDeviceRoot[i].fIsDeviceNodes);
+        RTTESTI_CHECK_MSG(   fAvailable
+                          == s_testCheckDeviceRoot[i].fAvailableExpected,
+                           ("USBProxyLinuxCheckDeviceRoot() returned %RTbool on line %i instead of %RTbool!\n",
+                            fAvailable, i,
+                            s_testCheckDeviceRoot[i].fAvailableExpected));
     }
 }
@@ -183,5 +192,6 @@
      * Run the tests.
      */
-    testEnvironment(hTest);
+    testInit(hTest);
+    testCheckDeviceRoot(hTest);
 
     /*
@@ -190,3 +200,2 @@
     return RTTestSummaryAndDestroy(hTest);
 }
-
