<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # TestInvocation ~~~ /** * {@inheritDoc} */ @Override public void invoke(ITestDevice device, IConfiguration config, IRescheduler rescheduler) throws DeviceNotAvailableException, Throwable { try { mStatus = "fetching build"; config.getLogOutput().init(); getLogRegistry().registerLogger(config.getLogOutput()); IBuildInfo info = null; if (config.getBuildProvider() instanceof IDeviceBuildProvider) { info = ((IDeviceBuildProvider) config.getBuildProvider()).getBuild(device); } else if (config.getBuildProvider() instanceof IDeviceConfigBuildProvider) { // 調用config獲得cts.xml文件中的<build_provider>標簽中對應的類,然后通過調用getBuild得到IBuildInfo對象 info = ((IDeviceConfigBuildProvider) config.getBuildProvider()).getBuild(device, config); } else { info = config.getBuildProvider().getBuild(); } if (info != null) { // System.out.println(String.format("setup: %s tearDown: %s", // config.getCommandOptions().isNeedPrepare(), // config.getCommandOptions().isNeedTearDown())); CLog.logAndDisplay(LogLevel.INFO, String.format("setup: %s tearDown: %s", config.getCommandOptions().isNeedPrepare(), config.getCommandOptions().isNeedTearDown())); // 獲取<test>配置項里的測試選項,并注入到info中 injectBuild(info, config.getTests()); if (shardConfig(config, info, rescheduler)) { CLog.i("Invocation for %s has been sharded, rescheduling", device.getSerialNumber()); } else { device.setRecovery(config.getDeviceRecovery()); // 準備刷機,啟動case performInvocation(config, device, info, rescheduler); // exit here, depend on performInvocation to deregister // logger return; } } else { mStatus = "(no build to test)"; CLog.d("No build to test"); rescheduleTest(config, rescheduler); } } catch (BuildRetrievalError e) { CLog.e(e); /* * because this is BuildRetrievalError, so do not generate test * result // report an empty invocation, so this error is sent to * listeners startInvocation(config, device, e.getBuildInfo()); // * don't want to use #reportFailure, since that will call * buildNotTested for (ITestInvocationListener listener : * config.getTestInvocationListeners()) { * listener.invocationFailed(e); } reportLogs(device, * config.getTestInvocationListeners(), config.getLogOutput()); * InvocationSummaryHelper.reportInvocationEnded( * config.getTestInvocationListeners(), 0); return; */ } catch (IOException e) { CLog.e(e); } // save current log contents to global log getLogRegistry().dumpToGlobalLog(config.getLogOutput()); getLogRegistry().unregisterLogger(); config.getLogOutput().closeLog(); } ~~~ 之所以稱為調度室,因為它就是去一步一步的運行9大組件的剩余組件,組件與組件之間并不知道對方的存在,只有TestInvocation自己知道。它通過反射的機制得到對象,分別創建對象,然后調用其中的接口方法得到它想要的,然后再傳給下一個組件。以上方法就可以看出,它先得到buildprovider對象。調用getBuild對象得到IBuildInfo對象。咱們這個程序中,其實就是調用了CtsBuildProvider的getBuild方法。 如果info不為null:然后給測試任務注入IBuildInfo,判斷是否可以分拆任務,如果不能分拆的話,注冊設備恢復類,然后跳轉到performInvocation方法中。 如果info為null:提示沒有可執行的build,調用IRescheduler.rescheduleCommand()重試。 ~~~ /** * Performs the invocation * * @param config * the {@link IConfiguration} * @param device * the {@link ITestDevice} to use. May be <code>null</code> * @param info * the {@link IBuildInfo} */ private void performInvocation(IConfiguration config, ITestDevice device, IBuildInfo info, IRescheduler rescheduler) throws Throwable { boolean resumed = false; long startTime = System.currentTimeMillis(); long elapsedTime = -1; info.setDeviceSerial(device.getSerialNumber()); startInvocation(config, device, info); try { device.setOptions(config.getDeviceOptions()); // 準備build和跑case prepareAndRun(config, device, info, rescheduler); } catch (BuildError e) { CLog.w("Build %s failed on device %s. Reason: %s", info.getBuildId(), device.getSerialNumber(), e.toString()); takeBugreport(device, config.getTestInvocationListeners(), BUILD_ERROR_BUGREPORT_NAME); reportFailure(e, config.getTestInvocationListeners(), config, info, rescheduler); } catch (TargetSetupError e) { CLog.e("Caught exception while running invocation"); CLog.e(e); reportFailure(e, config.getTestInvocationListeners(), config, info, rescheduler); // maybe test device if offline, check it device.waitForDeviceOnline(); } catch (DeviceNotAvailableException e) { // log a warning here so its captured before reportLogs is called CLog.w("Invocation did not complete due to device %s becoming not available. " + "Reason: %s", device.getSerialNumber(), e.getMessage()); if ((e instanceof DeviceUnresponsiveException) && TestDeviceState.ONLINE.equals(device.getDeviceState())) { // under certain cases it might still be possible to grab a // bugreport takeBugreport(device, config.getTestInvocationListeners(), DEVICE_UNRESPONSIVE_BUGREPORT_NAME); } resumed = resume(config, info, rescheduler, System.currentTimeMillis() - startTime); if (!resumed) { reportFailure(e, config.getTestInvocationListeners(), config, info, rescheduler); } else { CLog.i("Rescheduled failed invocation for resume"); } throw e; } catch (RuntimeException e) { // log a warning here so its captured before reportLogs is called CLog.w("Unexpected exception when running invocation: %s", e.toString()); reportFailure(e, config.getTestInvocationListeners(), config, info, rescheduler); throw e; } catch (AssertionError e) { CLog.w("Caught AssertionError while running invocation: ", e.toString()); reportFailure(e, config.getTestInvocationListeners(), config, info, rescheduler); } finally { mStatus = "done running tests"; try { // reportLogs(device, config.getTestInvocationListeners(), config.getLogOutput()); elapsedTime = System.currentTimeMillis() - startTime; if (!resumed) { // 發送報告 InvocationSummaryHelper.reportInvocationEnded(config.getTestInvocationListeners(), elapsedTime); } } finally { config.getBuildProvider().cleanUp(info); } } } ~~~ 首先啟動所有監聽器的start方法,起一個通知開始的作用。 ~~~ /** * Starts the invocation. * <p/> * Starts logging, and informs listeners that invocation has been started. * * @param config * @param device * @param info */ private void startInvocation(IConfiguration config, ITestDevice device, IBuildInfo info) { logStartInvocation(info, device); for (ITestInvocationListener listener : config.getTestInvocationListeners()) { try { listener.invocationStarted(info); } catch (RuntimeException e) { // don't let one listener leave the invocation in a bad state CLog.e("Caught runtime exception from ITestInvocationListener"); CLog.e(e); } } } ~~~ 然后得到device_options對象,設置到ITestDevice中。再調用prepareAndRun(config, device, info, rescheduler);方法。 ~~~ private void prepareAndRun(IConfiguration config, ITestDevice device, IBuildInfo info, IRescheduler rescheduler) throws Throwable { // use the JUnit3 logic for handling exceptions when running tests Throwable exception = null; try { // if (config.getCommandOptions().isNeedPrepare()&&!isRepeat) { doSetup(config, device, info); //下次啟動的時候,不再刷機 isRepeat = true; }else{ CLog.logAndDisplay(LogLevel.DEBUG, String.format("No need to flash,derect to run case")); } // 跑case runTests(device, info, config, rescheduler); } catch (Throwable running) { exception = running; } finally { try { if (config.getCommandOptions().isNeedTearDown()) { doTeardown(config, device, info, exception); } } catch (Throwable tearingDown) { if (exception == null) { exception = tearingDown; } } } if (exception != null) { throw exception; } } ~~~ 在該方法中先得到根據cmd_options得到是否需要prepare,如果需要,就調用target_prepare類來做準備工作,如果不需要,直接調用runTests方法 ~~~ private void runTests(ITestDevice device, IBuildInfo buildInfo, IConfiguration config, IRescheduler rescheduler) throws DeviceNotAvailableException { List<ITestInvocationListener> listeners = config.getTestInvocationListeners(); for (IRemoteTest test : config.getTests()) { if (test instanceof IDeviceTest) { ((IDeviceTest) test).setDevice(device); } test.run(new ResultForwarder(listeners)); } } ~~~ 上面的方法調用tests配置的類來追個調用里面的run方法啟動測試。測試完成后,來做tearDown的工作。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看