CTS Analysis Framework (4)-Adding tasks

Source: Internet
Author: User

Debug


watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvaxrmb290ymfsba==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">


The entrance to debug is in the Ctsconsole class, so we put the first breakpoint on line 249:


Console console = new Ctsconsole ();


Press F6 and press F5 to enter the Console.startconsole method.




Press F5 to enter the Globalconfiguration.createglobalconfiguration method.




In this method, the main is to read the global configuration file and set the Iglobalconfiguration interface object sinstance. The main method is to read the Getglobalconfigpath () of the file for 95 rows:


private static String Getglobalconfigpath () throws ConfigurationException {         String path = system.getenv (global_config_variable);        if (path! = null) {             //don ' t actually check for accessibility here, since the VARIABLE&NBSP ;           //might be specifying             //a Java resource rather than a filename. Even so, this can help            //the user figure out    &N bsp;       //which global config (if any) is picked up by tf.       &N bsp;    System.err                     .format ("Attempting to use global config \"%s\ "from Variable $%s.\n",       &Nbsp;                    path, Global_ config_variable);            return path;         }        file file = new file (global_config_filename);    & nbsp;   if (file.exists ()) {            path = File.getpath (); nbsp;           system.err.format (                      "Attempting to use auto Detected global config \"%s\ ". \ n",                     path);            system.err.flush ();            return path;        }        //Fixme:search in tradefed.sh launch Dir (or classpath?)

) return null; }


first infer whether the system variable of the global configuration file is set, assuming that there is no setting, then locate the Tf_global_config.xml file directly under the current file folder

Obviously, none of this program is. Therefore, the result of the method return should be null. Back to the Createglobalconfiguration (string[] args) method:


if (Globalconfigpath! = null) {//Found a global config file; attempt to parse and use itsinstance = Configfactory.createg Lobalconfigurationfromargs (Arrayutil.buildarray (new string[] {Globalconfigpath},args), NonGlobalArgs); System.err.format ("Success!  Using global config \ "%s\" \ n ", Globalconfigpath);} else {//Use default global configsinstance = new Globalconfiguration (); Nonglobalargs = Arrays.aslist (args);} return Nonglobalargs;

Because the path returned is null. So jump directly into the Else statement block, and new is not set regardless of the property. Finally, the command line parameters are encapsulated in the list, then the console sets the parameters and finally starts the thread to run the task. So the second breakpoint must be hit in the console's Run method. Then press F8 to enter the Run method.




The Run method infers some of the parameters first, assuming it is empty. Start the Commandscheduler thread. It's going to take the first element out of the running queue. Assume that the obtained queue is empty and will end.

Assume that the number of parameters is not null. Other operations, such as the following, are run in addition to starting the Commandscheduler thread:


public void Run () {list<string> Arrrgs = Mmainargs; Fallback, in case this isn ' t set already if (Mscheduler = = null) {Mscheduler = new Commandscheduler (        );            } try {//Check System.Console () since JLine doesn ' t seem to consistently know whether or not            The console is functional. if (!isconsolefunctional ()) {if (Arrrgs.isempty ()) {PrintLine ("No commands for Non-int Eractive mode;                    Exiting. ");                    Fixme:need to run the scheduler this things blocking on it//Fixme:will be released.                    Mscheduler.start ();                    Mscheduler.await ();                Return                    } else {printline ("non-interactive mode:running initial command then exiting.");                Mshouldexit = true; }}//Wait for the Commandscheduler to StArt. It'll hold the JVM open (since the Console//thread was a Daemon thread), and also we require it to having star            Ted So, we can//start processing user input.            Mscheduler.start ();            Mscheduler.await ();            String input = "";            Capturelist groups = new Capturelist ();            String[] tokens;  Note:since Console is a daemon thread, the JVM could exit without us actually leaving//this read loop.            This was by design.                    do {if (Arrrgs.isempty ()) {input = Getconsoleinput (); if (input = = null) {//Usually the result of getting EOF on the console pri                        Ntline (""); PrintLine ("Received EOF;                        Quitting ... ");                        Mshouldexit = true;                    Break                    } tokens = null;                     try {   tokens = Quotationawaretokenizer.tokenizeline (input);                        } catch (IllegalArgumentException e) {printline (String.Format ("Invalid input:%s.", input));                    Continue                    } if (tokens = = NULL | | tokens.length = = 0) {continue; }} else {PrintLine (String.Format ("Using commandline arguments as starting command:%s"                    , Arrrgs));                        if (Mconsolereader! = null) {//ADD the starting command as the first item in the console history                        Fixme:this won't properly escape commands that were properly escaped  Fixme:on the commandline.                        That said, it'll still is more convenient//Fixme:than copying by hand.              Final String cmd = Arrayutil.join ("", Arrrgs);          Mconsolereader.gethistory (). addtohistory (CMD);                    } tokens = Arrrgs.toarray (new string[0]);                Empty Arrrgs = Collections.emptylist ();                } Runnable command = Mcommandtrie.retrieve (groups, tokens);                if (command! = null) {executecmdrunnable (command, groups);  } else {PrintLine (String.Format ("Unable to handle command '%s ').                Enter ' help ' for help. ", Tokens[0]));            } runutil.getdefault (). Sleep (100);        } while (!mshouldexit); } catch (Exception e) {printline ("Console received an unexpected Exception (shown below);            Shutting down TF. ");        E.printstacktrace ();            } finally {Mscheduler.shutdown ();            Make sure, we don ' t quit with messages still in the buffers System.err.flush (); SYstem.out.flush (); }    }

The above code mainly looks at about 846 lines of

Executecmdrunnable (command, groups);


Let's look at the implementation of this approach:


/**     * Execute a command.     * <p/>     * Exposed for unit testing     *    /@SuppressWarnings ("unchecked")    void Executecmdrunnable ( Runnable command, capturelist groups) {        if (command instanceof argrunnable) {            //fixme:verify that command Implem Ents argrunnable<capturelist> instead            //fixme:of just argrunnable            ((argrunnable<capturelist>) command). Run (groups);        } else {            command.run ();        }    }

You will find that the program jumps to


((argrunnable<capturelist>) command). Run (groups);

Then press F5 to jump in. This time, the program went into the


watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvaxrmb290ymfsba==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">


So make a breakpoint in this place. Start Debug again, and you'll get into this place. The method calls the Commandscheduler.addcommand method and enters the method


/** * {@inheritDoc} */@Override public boolean AddCommand (string[] args, long totalexectime) {try {            Get information about the CTS configuration file iconfiguration config = getconfigfactory (). Createconfigurationfromargs (args); Print help information, just print the option information for the importance type if (Config.getcommandoptions (). Ishelpmode ()) {GETCONFIGFAC                Tory (). Printhelpforconfig (args, true, System.out);                System.out.flush (); Print all option information} else if (Config.getcommandoptions (). Isfullhelpmode ()) {getconfigfactory (). Prin            Thelpforconfig (args, false, System.out);  } else if (Config.getcommandoptions (). Isdryrunmode ()) {if (Config.getcommandoptions (). Isnoisydryrunmode ())                {Clog.loganddisplay (Loglevel.debug, "DRY RUN:%s", arrays.tostring (args)); } else {clog.d ("Dry run mode;                Skipping adding command:%s ", arrays.tostring (args));       }     } else {config.validateoptions ();                if (Config.getcommandoptions (). Runonalldevices ()) {addcommandforalldevices (totalexectime, args);                    } else {Commandtracker cmdtracker = Createcommandtracker (args);                    Cmdtracker.incrementexectime (Totalexectime);                    Executablecommand cmdinstance = Createexecutablecommand (cmdtracker, config, false);                Addexeccommandtoqueue (cmdinstance, 0);            } return true;            }} catch (ConfigurationException e) {e.printstacktrace (); Fixme:do this with JLine somehow-ANSI support//Note:make-Sure not-log (aka record) this line, as            (args) may contain passwords.            System.out.println (String.Format ("Error while processing args:%s", arrays.tostring (args));            System.out.println (E.getmessage ()); System.out.prinTLN ();    } return false; }

Let's look at the first line of code:


iconfiguration config = getconfigfactory (). Createconfigurationfromargs (args);

The method finds the XML file under the Config folder based on the second parameter in the parameter, reads the contents, and then configures the 9 components of the CTS framework (this is in the next article).

When the Config object is obtained, it is inferred that the full device execution or individual device execution is performed by default. Assuming a single device execution, you need to specify the SN number of the device, and the framework finds the device based on the SN number. Finally, the execution plan is put into the queue.




The addition of this task is complete. The task queue is constantly accepting new tasks, and then there is a loop in the Commandscheduler run method. Take the first task and run it every time.


 try {//Notify other threads that we ' re running.                        Mrunlatch.countdown ();            Idevicemanager manager = Getdevicemanager ();                while (!isshutdown ()) {Executablecommand cmd = Dequeueconfigcommand ();                    if (cmd! = null) {ideviceselection options = Cmd.getconfiguration (). getdevicerequirements ();                    Itestdevice device = Manager.allocatedevice (0, options); if (device! = NULL) {//Spawn off a thread to perform the invocation Invoca                        Tionthread Invthread = startinvocation (manager, device, CMD);                        Addinvocationthread (Invthread);                        if (Cmd.isloopmode ()) {Addnewexeccommandtoqueue (Cmd.getcommandtracker ());                        }} else {//no device available for command, put the back in queue // Increment exec time to ensure fair scheduling among commands when devices//is scarce                        Cmd.getcommandtracker (). Incrementexectime (1);                        Addexeccommandtoqueue (cmd, no_device_delay_time);                    Clog.loganddisplay (Loglevel.error,string.format ("Can ' t find device%s.", Options.getserials ()));            }}} mcommandtimer.shutdown ();            CLOG.I ("Waiting for invocation threads-complete");            List<invocationthread> threadlistcopy;                Synchronized (this) {threadlistcopy = new arraylist<invocationthread> (Minvocationthreads.size ());            Threadlistcopy.addall (minvocationthreads);            } for (thread thread:threadlistcopy) {waitforthread (thread);            } closeremoteclient (); if (Mremotemanager! = null) {Mremotemanager.cancel ();           } exit (manager);            CleanUp ();        Clog.loganddisplay (Loglevel.info, "all done");            } finally {//Make sure that we don ' t quit with messages still in the buffers System.err.flush ();        System.out.flush (); }

The addition of this task is done. The next article resolves how the configuration file is parsed.

Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.

CTS Analysis Framework (4)-Adding tasks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.