예제 #1
0
        /// <summary>
        /// Runs an <see cref="IJobManager"/> with all implementations of <see cref="IJobRunner"/>.
        /// </summary>
        /// <param name="jobManager">The job manager to run.</param>
        /// <param name="onSimulationCompleted">Event handler which will be invoked by each job runner after it finishes running.</param>
        private void TestWithAllJobRunners(IJobManager jobManager, EventHandler <AllCompletedArgs> onSimulationCompleted)
        {
            IJobRunner jobRunner = new JobRunnerSync();

            jobRunner.AllJobsCompleted += onSimulationCompleted;
            Assert.DoesNotThrow(() => jobRunner.Run(jobManager, true));

            jobRunner.AllJobsCompleted -= onSimulationCompleted;

            jobRunner = new JobRunnerAsync();
            jobRunner.AllJobsCompleted += onSimulationCompleted;
            Assert.DoesNotThrow(() => jobRunner.Run(jobManager, true));

            jobRunner.AllJobsCompleted -= onSimulationCompleted;

            jobRunner = new JobRunnerMultiProcess(false);
            jobRunner.AllJobsCompleted += onSimulationCompleted;
            Assert.DoesNotThrow(() => jobRunner.Run(jobManager, true));
            jobRunner.AllJobsCompleted -= onSimulationCompleted;
        }
예제 #2
0
        /// <summary>
        /// Main program entry point.
        /// </summary>
        /// <param name="args"> Command line arguments</param>
        /// <returns> Program exit code (0 for success)</returns>
        public static int Main(string[] args)
        {
            int exitCode = 0;

            try
            {
                string fileName = null;

                // Extract file name from command line arguments.
                if (args.Length >= 1)
                {
                    fileName = args[0];
                }

                string usageMessage = "Usage: Models ApsimXFileSpec [/Recurse] [/SingleThreaded] [/RunTests] [/Csv] [/Version] [/Verbose] [/Upgrade] [/m] [/?]";
                if (args.Contains("/?"))
                {
                    string detailedHelpInfo = usageMessage;
                    detailedHelpInfo += Environment.NewLine + Environment.NewLine;
                    detailedHelpInfo += "ApsimXFileSpec:          The path to an .apsimx file. May include wildcard.";
                    detailedHelpInfo += Environment.NewLine + Environment.NewLine + "Options:" + Environment.NewLine;
                    detailedHelpInfo += "    /Recurse             Recursively search subdirectories for files matching ApsimXFileSpec" + Environment.NewLine;
                    detailedHelpInfo += "    /SingleThreaded      Run all simulations in a single thread." + Environment.NewLine;
                    detailedHelpInfo += "    /RunTests            Run all tests." + Environment.NewLine;
                    detailedHelpInfo += "    /Csv                 Export all reports to .csv files." + Environment.NewLine;
                    detailedHelpInfo += "    /Version             Display the version number." + Environment.NewLine;
                    detailedHelpInfo += "    /Verbose             Write messages to StdOut when a simulation starts/finishes. Only has an effect when running a directory of .apsimx files (*.apsimx)." + Environment.NewLine;
                    detailedHelpInfo += "    /Upgrade             Upgrades a file to the latest version of the .apsimx file format. Does not run the file." + Environment.NewLine;
                    detailedHelpInfo += "    /m                   Use the experimental multi-process job runner." + Environment.NewLine;
                    detailedHelpInfo += "    /?                   Show detailed help information.";
                    Console.WriteLine(detailedHelpInfo);
                    return(1);
                }

                if (args.Length < 1 || args.Length > 10)
                {
                    Console.WriteLine(usageMessage);
                    return(1);
                }

                if (args.Contains("/Version"))
                {
                    Model m = new Model();
                    Console.WriteLine(m.ApsimVersion);
                    return(0);
                }

                if (args.Contains("/Upgrade"))
                {
                    string dir = Path.GetDirectoryName(fileName);
                    if (string.IsNullOrWhiteSpace(dir))
                    {
                        dir = Directory.GetCurrentDirectory();
                    }
                    string[] files = Directory.EnumerateFiles(dir, Path.GetFileName(fileName), args.Contains("/Recurse") ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToArray();
                    foreach (string file in files)
                    {
                        List <Exception> errors;
                        IModel           sims = FileFormat.ReadFromFile <Model>(file, out errors);
                        if (errors != null && errors.Count > 0)
                        {
                            foreach (Exception error in errors)
                            {
                                Console.Error.WriteLine(error.ToString());
                            }
                        }
                        File.WriteAllText(file, FileFormat.WriteToString(sims));
                        Console.WriteLine("Successfully upgraded " + file);
                    }
                    return(0);
                }

                Stopwatch timer = new Stopwatch();
                timer.Start();

                // If the filename argument has a wildcard then create a IJobManager to go look for matching files to run.
                // Otherwise, create a JobManager to open the filename and run it in a separate, external process
                IJobManager job;
                bool        hasWildcard = fileName.Contains('*') || fileName.Contains('?');
                if (hasWildcard)
                {
                    job = Runner.ForFolder(fileName, args.Contains("/Recurse"), args.Contains("/RunTests"), args.Contains("/Verbose"), args.Contains("/m"));
                }
                else
                {
                    job = Runner.ForFile(fileName, args.Contains("/RunTests"));
                }

                // Run the job created above using either a single thread or multi threaded (default)
                IJobRunner jobRunner;
                if (args.Contains("/SingleThreaded"))
                {
                    jobRunner = new JobRunnerSync();
                }
                else if (args.Contains("/m"))
                {
                    // If the multi-process switch has been provided as well as a wildcard in the filename,
                    // we want to use the single threaded job runner, but run each job in multi-process mode.
                    // TODO : might be useful to allow users to run a directory of apsimx files via the multi-
                    // process job runner. This could be faster if they have many small files.
                    if (hasWildcard)
                    {
                        jobRunner = new JobRunnerSync();
                    }
                    else
                    {
                        jobRunner = new JobRunnerMultiProcess(args.Contains("/Verbose"));
                    }
                }
                else
                {
                    jobRunner = new JobRunnerAsync();
                }
                if (args.Select(arg => arg.ToLower()).Contains("/csv"))
                {
                    string dir = Path.GetDirectoryName(fileName);
                    if (dir == "")
                    {
                        dir = Directory.GetCurrentDirectory();
                    }
                    files = Directory.GetFiles(
                        dir,
                        Path.GetFileName(fileName),
                        args.Contains("/Recurse") ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList();
                    jobRunner.AllJobsCompleted += GenerateCsvFiles;
                }
                jobRunner.JobCompleted     += OnJobCompleted;
                jobRunner.AllJobsCompleted += OnAllJobsCompleted;
                jobRunner.Run(job, wait: true);

                // If errors occurred, write them to the console.
                if (errors != string.Empty)
                {
                    Console.WriteLine("ERRORS FOUND!!");
                    Console.WriteLine(errors);
                    exitCode = 1;
                }
                else
                {
                    exitCode = 0;
                }

                timer.Stop();
                Console.WriteLine("Finished running simulations. Duration " + timer.Elapsed.TotalSeconds.ToString("#.00") + " sec.");
            }
            catch (Exception err)
            {
                Console.WriteLine(err.ToString());
                exitCode = 1;
            }

            return(exitCode);
        }