Exemplo n.º 1
0
        def _start_executing(res=None):
            if _start_flag.is_set():
                return
            _start_flag.set()

            logging.info("Start execute test plan with IDE version: %d",
                         XCODE_VERSION)
            ManagerdLockdown2._call(False, 0xFFFFFFFF, '_IDE_startExecutingTestPlanWithProtocolVersion:',
                                    DTXServerRPCRawObj(XCODE_VERSION))
Exemplo n.º 2
0
        def _start_executing(res=None):
            if _start_flag.is_set():
                return
            _start_flag.set()

            logging.info(" _start_executing Start execute test plan with IDE version: %d",
                         xcode_version)
            manager_lock_down_2._call(False, 0xFFFFFFFF, '_IDE_startExecutingTestPlanWithProtocolVersion:',
                                      DTXServerRPCRawObj(xcode_version))
Exemplo n.º 3
0
    def run(self) -> None:
        def _callback(res):
            self.callback(get_auxiliary_text(res.raw))

        lock_down = LockdownClient(udid=self.device_id)
        installation = InstallationProxy(lockdown=lock_down)
        app_info = installation.find_bundle_id(self.bundle_id)
        if not app_info:
            raise Exception("No app matches", self.bundle_id)
        logging.info("BundleID: %s", self.bundle_id)
        logging.info("DeviceIdentifier: %s",
                     lock_down.device_info.get('UniqueDeviceID'))
        sign_identity = app_info.get("SignerIdentity", "")
        logging.info("SignIdentity: %r", sign_identity)
        xcode_version = 29
        session_identifier = NSUUID('96508379-4d3b-4010-87d1-6483300a7b76')
        manager_lock_down_1 = TestManagerdLockdown(lock_down).init()

        manager_lock_down_1._make_channel(
            "dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface"
        )
        if lock_down.ios_version > LooseVersion('11.0'):
            result = manager_lock_down_1.call(
                "dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface",
                "_IDE_initiateControlSessionWithProtocolVersion:",
                DTXServerRPCRawObj(xcode_version)).parsed
            logging.info("result: %s", result)
        manager_lock_down_1.register_callback(DTXEnum.FINISHED,
                                              lambda _: self.quit_event.set())
        manager_lock_down_1.register_unhandled_callback(_callback)

        manager_lock_down_2 = TestManagerdLockdown(lock_down).init()
        manager_lock_down_2._make_channel(
            "dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface"
        )
        manager_lock_down_2.register_callback(DTXEnum.FINISHED,
                                              lambda _: self.quit_event.set())
        manager_lock_down_2.register_unhandled_callback(_callback)

        _start_flag = threading.Event()

        def _start_executing(res=None):
            if _start_flag.is_set():
                return
            _start_flag.set()

            logging.info(
                " _start_executing Start execute test plan with IDE version: %d",
                xcode_version)
            manager_lock_down_2._call(
                False, 0xFFFFFFFF,
                '_IDE_startExecutingTestPlanWithProtocolVersion:',
                DTXServerRPCRawObj(xcode_version))

        def _show_log_message(res):
            logging.info(f"{res.parsed} : {get_auxiliary_text(res.raw)}")
            if 'Received test runner ready reply with error: (null' in ''.join(
                    get_auxiliary_text(res.raw)):
                logging.info("_start_executing Test runner ready detected")
                _start_executing()

        manager_lock_down_2.register_callback(
            '_XCT_testBundleReadyWithProtocolVersion:minimumVersion:',
            _start_executing)
        manager_lock_down_2.register_callback('_XCT_logDebugMessage:',
                                              _show_log_message)
        manager_lock_down_2.register_callback(
            '_XCT_didFinishExecutingTestPlan', lambda _: self.quit_event.set())

        result = manager_lock_down_2.call(
            'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
            '_IDE_initiateSessionWithIdentifier:forClient:atPath:protocolVersion:',
            DTXServerRPCRawObj(
                session_identifier,
                str(session_identifier) + '-6722-000247F15966B083',
                '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild',
                xcode_version)).parsed
        logging.info("_start_executing result: %s", result)
        # launch_wda
        xctest_path = "/tmp/WebDriverAgentRunner-" + str(
            session_identifier).upper() + ".xctestconfiguration"
        xctest_content = archive(
            XCTestConfiguration({
                "testBundleURL":
                NSURL(
                    None, "file://" + app_info['Path'] +
                    "/PlugIns/WebDriverAgentRunner.xctest"),
                "sessionIdentifier":
                session_identifier,
            }))

        fsync = HouseArrestClient(udid=self.device_id)
        fsync.send_command(self.bundle_id)
        for fname in fsync.read_directory("/tmp"):
            if fname.endswith(".xctestconfiguration"):
                logging.debug("remove /tmp/%s", fname)
                fsync.file_remove("/tmp/" + fname)
        fsync.set_file_contents(xctest_path, xctest_content)

        conn = InstrumentServer(lock_down).init()
        conn.call('com.apple.instruments.server.services.processcontrol',
                  'processIdentifierForBundleIdentifier:', self.bundle_id)

        conn.register_unhandled_callback(_callback)
        app_path = app_info['Path']
        app_container = app_info['Container']

        xctestconfiguration_path = app_container + xctest_path
        logging.info("AppPath: %s", app_path)
        logging.info("AppContainer: %s", app_container)

        app_env = {
            'CA_ASSERT_MAIN_THREAD_TRANSACTIONS': '0',
            'CA_DEBUG_TRANSACTIONS': '0',
            'DYLD_FRAMEWORK_PATH': app_path + '/Frameworks:',
            'DYLD_LIBRARY_PATH': app_path + '/Frameworks',
            'NSUnbufferedIO': 'YES',
            'SQLITE_ENABLE_THREAD_ASSERTIONS': '1',
            'WDA_PRODUCT_BUNDLE_IDENTIFIER': '',
            'XCTestConfigurationFilePath': xctestconfiguration_path,
            'XCODE_DBG_XPC_EXCLUSIONS': 'com.apple.dt.xctestSymbolicator',
            'MJPEG_SERVER_PORT': '',
            'USE_PORT': '',
        }
        if self.app_env:
            app_env.update(self.app_env)
        if lock_down.ios_version > LooseVersion('11.0'):
            app_env[
                'DYLD_INSERT_LIBRARIES'] = '/Developer/usr/lib/libMainThreadChecker.dylib'
            app_env['OS_ACTIVITY_DT_MODE'] = 'YES'
        app_options = {'StartSuspendedKey': False}
        if lock_down.ios_version > LooseVersion('12.0'):
            app_options['ActivateSuspended'] = True

        app_args = [
            '-NSTreatUnknownArgumentsAsOpen', 'NO',
            '-ApplePersistenceIgnoreState', 'YES'
        ]

        identifier = "launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:"

        pid = conn.call('com.apple.instruments.server.services.processcontrol',
                        identifier, app_path, self.bundle_id, app_env,
                        app_args, app_options).parsed
        if not isinstance(pid, int):
            logging.error(f"Launch failed: {pid}")
            raise Exception("Launch failed")

        logging.info(f" Launch {self.bundle_id} pid: {pid}")

        conn.call('com.apple.instruments.server.services.processcontrol',
                  "startObservingPid:", DTXServerRPCRawObj(pid))

        if self.quit_event:
            conn.register_callback(DTXEnum.FINISHED,
                                   lambda _: self.quit_event.set())

        if lock_down.ios_version > LooseVersion('12.0'):
            identifier = '_IDE_authorizeTestSessionWithProcessID:'
            result = manager_lock_down_1.call(
                'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
                identifier, DTXServerRPCRawObj(pid)).parsed
            logging.info("_IDE_authorizeTestSessionWithProcessID: %s", result)
        else:
            identifier = '_IDE_initiateControlSessionForTestProcessID:protocolVersion:'
            result = manager_lock_down_1.call(
                'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
                identifier, DTXServerRPCRawObj(pid, xcode_version)).parsed
            logging.info("_IDE_authorizeTestSessionWithProcessID: %s", result)

        while not self.quit_event.wait(.1):
            pass
        logging.warning("xctrunner quited")
        conn.stop()
        manager_lock_down_2.stop()
        manager_lock_down_1.stop()