public void AddStockGenotype() { var simulations = new Simulations() { Children = new List <IModel>() { new Models.GrazPlan.Stock() } }; var fileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); simulations.Write(fileName); var explorerPresenter = UITestsMain.MasterPresenter.OpenApsimXFileInTab(fileName, onLeftTabControl: true); GtkUtilities.WaitForGtkEvents(); var stock = explorerPresenter.ApsimXFile.FindInScope <Models.GrazPlan.Stock>(); explorerPresenter.SelectNode(stock); explorerPresenter.ContextMenu.AddModel(explorerPresenter, EventArgs.Empty); GtkUtilities.WaitForGtkEvents(); TreeView addModelsTree = (TreeView)ReflectionUtilities.GetValueOfFieldOrProperty("tree", explorerPresenter.CurrentPresenter); // Let's make sure we can add stock genotype resource - e.g. Angus. ActivateNode(addModelsTree, ".Models.GrazPlan.Genotypes.Cattle.Beef.Angus"); Assert.AreEqual(1, stock.Children.Count); Assert.AreEqual(typeof(Genotype), stock.Children[0].GetType()); var genotype = stock.Children[0] as Genotype; Assert.AreEqual("Angus", genotype.Name); Assert.AreEqual(500, genotype.BreedSRW); }
/// <summary> /// Runs models.exe on the given sims and passes along the given command line arguments. /// Returns StdOut of Models.exe. /// </summary> /// <param name="sims">Simulations to be run.</param> /// <param name="arguments">Command line arguments to be passed to Models.exe.</param> public static string RunModels(Simulations sims, string arguments) { sims.FileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); sims.Write(sims.FileName); string pathToModels = typeof(IModel).Assembly.Location; return(RunModels(sims.FileName + " " + arguments)); }
public static ExplorerPresenter OpenBasicFileInGui() { Simulations sims = UnitTests.Utilities.GetRunnableSim(); string fileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); sims.Write(fileName); return(UITestsMain.MasterPresenter.OpenApsimXFileInTab(fileName, onLeftTabControl: true)); }
public void Initialise() { Simulations basicFile = Utilities.GetRunnableSim(); IModel simulation = Apsim.Find(basicFile, typeof(Simulation)); IModel paddock = Apsim.Find(basicFile, typeof(Zone)); // Add a weather component. Models.Weather weather = new Models.Weather(); weather.Name = "Weather"; weather.FileName = "asdf.met"; Structure.Add(weather, simulation); // Add a second weather component. Models.Weather weather2 = new Models.Weather(); weather2.FileName = "asdf.met"; weather2.Name = "Weather2"; Structure.Add(weather2, simulation); // Add a third weather component. Models.Weather weather3 = new Models.Weather(); weather3.FileName = "asdf.met"; weather3.Name = "Weather3"; Structure.Add(weather3, simulation); // Add a third weather component. Models.Weather weather4 = new Models.Weather(); weather4.FileName = "asdf.met"; weather4.Name = "Weather4"; Structure.Add(weather4, simulation); // Add a report. Models.Report report = new Models.Report(); report.Name = "Report"; Structure.Add(report, paddock); basicFile.Write(basicFile.FileName); fileName = basicFile.FileName; // Create a new .apsimx file containing two weather nodes. Simulations test = Utilities.GetRunnableSim(); IModel sim = Apsim.Find(test, typeof(Simulation)); Models.Weather w1 = new Models.Weather(); w1.FileName = "w1.met"; w1.Name = "w1"; Structure.Add(w1, sim); Models.Weather w2 = new Models.Weather(); w2.Name = "w2"; w2.FileName = "w2.met"; Structure.Add(w2, sim); extFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".apsimx"); test.Write(extFile); }
public void TestSimNameRegex() { string models = typeof(IModel).Assembly.Location; IModel sim1 = Utilities.GetRunnableSim().Children[1]; sim1.Name = "sim1"; IModel sim2 = Utilities.GetRunnableSim().Children[1]; sim2.Name = "sim2"; IModel sim3 = Utilities.GetRunnableSim().Children[1]; sim3.Name = "simulation3"; IModel sim4 = Utilities.GetRunnableSim().Children[1]; sim4.Name = "Base"; Simulations sims = Simulations.Create(new[] { sim1, sim2, sim3, sim4, new DataStore() }); sims.ParentAllDescendants(); string apsimxFileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); sims.Write(apsimxFileName); // Need to quote the regex on unix systems. string args; args = @"/Verbose /SimulationNameRegexPattern:sim\d"; string stdout = Utilities.RunModels(sims, args); Assert.True(stdout.Contains("sim1")); Assert.True(stdout.Contains("sim2")); Assert.False(stdout.Contains("simulation3")); Assert.False(stdout.Contains("Base")); args = @"/Verbose /SimulationNameRegexPattern:sim1"; stdout = Utilities.RunModels(sims, args); Assert.True(stdout.Contains("sim1")); Assert.False(stdout.Contains("sim2")); Assert.False(stdout.Contains("simulation3")); Assert.False(stdout.Contains("Base")); args = @"/Verbose /SimulationNameRegexPattern:(simulation3)|(Base)"; stdout = Utilities.RunModels(sims, args); Assert.False(stdout.Contains("sim1")); Assert.False(stdout.Contains("sim2")); Assert.True(stdout.Contains("simulation3")); Assert.True(stdout.Contains("Base")); }
public void TestFileNameChange() { Simulations sims = Utilities.GetRunnableSim(); IDataStore storage = Apsim.Find(sims, typeof(IDataStore)) as IDataStore; // Write the simulations to disk. sims.Write(sims.FileName); // Record the database's filename. string oldDbFileName = storage.FileName; // Write the simulations to disk under a new filename. sims.Write(Path.ChangeExtension(Path.GetTempFileName(), ".apsimx")); // Record the database's new filename. string newDbFileName = storage.FileName; // The new file name should not be the same as the old one. Assert.AreNotEqual(oldDbFileName, newDbFileName); }
/// <summary> /// Generates an .apsimx file containing replacements model (if it /// exists), a datastore, and all children of this model. Saves the /// file to disk and returns the absolute path to the file. /// </summary> private string GenerateApsimXFile() { Simulations rootNode = FindAncestor <Simulations>(); string apsimxFileName = GetTempFileName($"apsimx_file_{id}", ".apsimx"); Simulations sims = new Simulations(); sims.Children.AddRange(Children.Select(c => Apsim.Clone(c))); sims.Children.RemoveAll(c => c is IDataStore); IModel replacements = this.FindInScope <Replacements>(); if (replacements != null && !sims.Children.Any(c => c is Replacements)) { sims.Children.Add(Apsim.Clone(replacements)); } // Search for IDataStore, not DataStore - to allow for StorageViaSockets. IDataStore storage = this.FindInScope <IDataStore>(); IModel newDataStore = new DataStore(); if (storage != null && storage is IModel m) { newDataStore.Children.AddRange(m.Children.Select(c => Apsim.Clone(c))); } sims.Children.Add(newDataStore); sims.ParentAllDescendants(); sims.Write(apsimxFileName); string originalFile = rootNode?.FileName; if (string.IsNullOrEmpty(originalFile)) { originalFile = storage?.FileName; } // Copy files across. foreach (IReferenceExternalFiles fileReference in sims.FindAllDescendants <IReferenceExternalFiles>().Cast <IReferenceExternalFiles>()) { foreach (string file in fileReference.GetReferencedFileNames()) { string absoluteFileName = PathUtilities.GetAbsolutePath(file, originalFile); string fileName = Path.GetFileName(absoluteFileName); string newPath = Path.GetDirectoryName(sims.FileName); File.Copy(absoluteFileName, Path.Combine(newPath, fileName), true); } } return(apsimxFileName); }
/// <summary> /// Generates an .apsimx file containing replacements model (if it /// exists), a datastore, and all children of this model. Saves the /// file to disk and returns the absolute path to the file. /// </summary> private string GenerateApsimXFile() { Simulations rootNode = (Apsim.Parent(this, typeof(Simulations)) as Simulations); string apsimxFileName = GetTempFileName($"apsimx_file_{id}", ".apsimx"); Simulations sims = new Simulations(); sims.Children.AddRange(Children.Select(c => Apsim.Clone(c))); sims.Children.RemoveAll(c => c is IDataStore); IModel replacements = Apsim.Find(this, typeof(Replacements)); if (replacements != null && !sims.Children.Any(c => c is Replacements)) { sims.Children.Add(Apsim.Clone(replacements)); } IModel storage = Apsim.Find(this, typeof(IDataStore)); IModel newDataStore = new DataStore(); if (storage != null) { newDataStore.Children.AddRange(storage.Children.Select(c => Apsim.Clone(c))); } sims.Children.Add(newDataStore); Apsim.ParentAllChildren(sims); sims.Write(apsimxFileName); string originalFile = rootNode?.FileName; if (string.IsNullOrEmpty(originalFile)) { originalFile = (storage as IDataStore)?.FileName; } // Copy files across. foreach (IReferenceExternalFiles fileReference in Apsim.ChildrenRecursively(sims, typeof(IReferenceExternalFiles)).Cast <IReferenceExternalFiles>()) { foreach (string file in fileReference.GetReferencedFileNames()) { string absoluteFileName = PathUtilities.GetAbsolutePath(file, originalFile); string fileName = Path.GetFileName(absoluteFileName); string newPath = Path.GetDirectoryName(sims.FileName); File.Copy(absoluteFileName, Path.Combine(newPath, fileName), true); } } return(apsimxFileName); }
/// <summary> /// Edits a single apsimx file according to the changes specified in the config file. /// </summary> /// <param name="apsimxFileName">Path to an .apsimx file.</param> /// <param name="factors">Factors to apply to the file.</param> private static void EditFile(string apsimxFileName, List <CompositeFactor> factors) { Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw new Exception($"Error reading file ${apsimxFileName}: {errors[0].ToString()}"); } foreach (CompositeFactor factor in factors) { IVariable variable = Apsim.GetVariableObject(file, factor.Paths[0]); variable.Value = ReflectionUtilities.StringToObject(variable.DataType, factor.Values[0].ToString()); } file.Write(apsimxFileName); }
/// <summary> /// Returns a lightweight skeleton simulation which can be run. /// </summary> public static Simulations GetRunnableSim() { Simulations sims = new Simulations() { FileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"), Children = new List <IModel>() { new DataStore(), new Simulation() { Children = new List <IModel>() { new Clock() { StartDate = new DateTime(2017, 1, 1), EndDate = new DateTime(2017, 1, 10) // January 10 }, new Summary(), new Zone() { Area = 1, Children = new List <IModel>() { new Models.Report() { VariableNames = new string[] { "[Clock].Today.DayOfYear as n" }, EventNames = new string[] { "[Clock].DoReport" } } } } } } } }; sims.ParentAllDescendants(); sims.Write(sims.FileName); return(sims); }
public void RefreshCheckpointNames() { Simulations sims = Utilities.GetRunnableSim(); sims.FileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".apsimx"); sims.Write(sims.FileName); Simulation sim = sims.FindInScope <Simulation>(); IDataStore storage = sims.FindInScope <IDataStore>(); // Record checkpoint names before and after running the simulation, // and ensure that they are not the same. string[] checkpointNamesBeforeRun = storage.Reader.CheckpointNames.ToArray(); // Run the simulation var runner = new Runner(sims); runner.Run(); string[] checkpointNamesAfterRun = storage.Reader.CheckpointNames.ToArray(); Assert.AreNotEqual(checkpointNamesBeforeRun, checkpointNamesAfterRun, "Storage reader failed to update checkpoint names after simulation was run."); }
public void RefreshCheckpointNames() { Simulations sims = Utilities.GetRunnableSim(); sims.FileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".apsimx"); sims.Write(sims.FileName); Simulation sim = Apsim.Find(sims, typeof(Simulation)) as Simulation; IDataStore storage = Apsim.Find(sims, typeof(IDataStore)) as IDataStore; // Record checkpoint names before and after running the simulation, // and ensure that they are not the same. string[] checkpointNamesBeforeRun = storage.Reader.CheckpointNames.ToArray(); // Run the simulation IJobManager jobManager = new RunOrganiser(sims, sim, false); IJobRunner jobRunner = new JobRunnerAsync(); jobRunner.Run(jobManager, wait: true); string[] checkpointNamesAfterRun = storage.Reader.CheckpointNames.ToArray(); Assert.AreNotEqual(checkpointNamesBeforeRun, checkpointNamesAfterRun, "Storage reader failed to update checkpoint names after simulation was run."); }
/// <summary>Called to start the job.</summary> /// <param name="jobManager">The job manager running this job.</param> /// <param name="workerThread">The thread this job is running on.</param> public void Run(JobManager jobManager, BackgroundWorker workerThread) { simulations.Write(simulations.FileName); }
public void CreateGraphs() { Simulations sims = CreateTemplate(); sims.FileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); DataStore storage = sims.FindInScope <DataStore>(); storage.FileName = Path.ChangeExtension(sims.FileName, ".db"); // Run the file to populate the datastore. Runner runner = new Runner(sims); List <Exception> errors = runner.Run(); if (errors != null && errors.Count > 0) { throw errors[0]; } // Open the .apsimx file in the GUI. sims.Write(sims.FileName); ExplorerPresenter explorer = UITestsMain.MasterPresenter.OpenApsimXFileInTab(sims.FileName, true); GtkUtilities.WaitForGtkEvents(); sims = explorer.ApsimXFile; // Create a graphs folder under the zone. IModel paddock = sims.FindInScope <Zone>(); Folder graphs = new Folder(); graphs.Name = "Graphs"; var command = new AddModelCommand(paddock, graphs); explorer.CommandHistory.Add(command, true); // Add an empty graph to the folder. Models.Graph graph = new Models.Graph(); graph.Name = "Graph"; command = new AddModelCommand(graphs, graph); explorer.CommandHistory.Add(command, true); // Add an empty series to the graph. Models.Series series = new Models.Series(); series.Name = "Series"; command = new AddModelCommand(graph, series); explorer.CommandHistory.Add(command, true); explorer.Refresh(); // click on the series node. explorer.SelectNode(series.FullPath); GtkUtilities.WaitForGtkEvents(); // Get a reference to the OxyPlot PlotView via reflection. SeriesView seriesView = explorer.CurrentRightHandView as SeriesView; GraphView view = seriesView?.GraphView as GraphView; Assert.NotNull(view); PlotView plot = ReflectionUtilities.GetValueOfFieldOrProperty("plot1", view) as PlotView; Assert.NotNull(plot); // Series has no table name or x/y series names yet, so there should // be nothing shown on the graph. Assert.AreEqual(0, plot.Model.Series.Count); // Now draw some data on the graph. seriesView.DataSource.SelectedValue = "Report"; seriesView.X.SelectedValue = "n"; seriesView.Y.SelectedValue = "n2"; seriesView.SeriesType.SelectedValue = "Scatter"; GtkUtilities.WaitForGtkEvents(); // There should now be one series showing. Assert.AreEqual(1, plot.Model.Series.Count); // It should be a line series. Assert.True(plot.Model.Series[0] is LineSeries, "Graph series type is set to scatter, but the series object is not a LineSeries."); // Series colour should not be white, and should not be the same as the background colour. LineSeries line = plot.Model.Series[0] as LineSeries; OxyPlot.OxyColor empty = OxyPlot.OxyColor.FromArgb(0, 0, 0, 0); OxyPlot.OxyColor white = OxyPlot.OxyColor.FromArgb(0, 255, 255, 255); Assert.AreNotEqual(empty, line.Color, "Graph line series default colour is white on white."); Assert.AreNotEqual(white, line.Color, "Graph line series default colour is white on white."); // Legend should be visible but empty by default. Assert.True(plot.Model.IsLegendVisible); // todo - ensure legend is empty // Next, we want to change the legend position and ensure that the legend actually moves. // Click on the 'show in legend' checkbox. seriesView.ShowInLegend.Checked = true; GtkUtilities.WaitForGtkEvents(); // Double click on the middle of the legend. Cairo.Rectangle legendRect = plot.Model.LegendArea.ToRect(true); double x = (legendRect.X + (legendRect.X + legendRect.Width)) / 2; double y = (legendRect.Y + (legendRect.Y + legendRect.Height)) / 2; GtkUtilities.DoubleClick(plot, x, y, wait: true); // Default legend position should be top-left. Assert.AreEqual(plot.Model.LegendPosition, OxyPlot.LegendPosition.TopLeft); // Now we want to change the legend position. First, get a reference to the legend view // via the legend presenter, via the graph presenter, via the series presenter, via the explorer presenter. Assert.True(explorer.CurrentPresenter is SeriesPresenter); SeriesPresenter seriesPresenter = explorer.CurrentPresenter as SeriesPresenter; LegendPresenter legendPresenter = seriesPresenter.GraphPresenter.CurrentPresenter as LegendPresenter; // todo: should we add something like a GetView() method to the IPresenter interface? // It might be a bit of work to set up but would save us having to use reflection LegendView legendView = ReflectionUtilities.GetValueOfFieldOrProperty("view", legendPresenter) as LegendView; // The legend options are inside a Gtk expander. Assert.IsTrue(legendView.MainWidget.Parent is Expander); Expander expander = legendView.MainWidget.Parent as Expander; // The expander should be expanded and the options visible. Assert.IsTrue(expander.Expanded); Assert.IsTrue(legendView.MainWidget.Visible); // The legend view contains a combo box with the legend position options (top-right, bottom-left, etc). // This should really be refactored to use a public IDropDownView, which is much more convenient to use. // First, get a reference to the combo box via reflection. ComboBox combo = ReflectionUtilities.GetValueOfFieldOrProperty("combobox1", legendView) as ComboBox; // fixme - we should support all valid OxyPlot legend position types. foreach (Models.Graph.LegendPositionType legendPosition in Enum.GetValues(typeof(Models.Graph.LegendPositionType))) { string name = legendPosition.ToString(); GtkUtilities.SelectComboBoxItem(combo, name, wait: true); OxyPlot.LegendPosition oxyPlotEquivalent = (OxyPlot.LegendPosition)Enum.Parse(typeof(OxyPlot.LegendPosition), name); Assert.AreEqual(plot.Model.LegendPosition, oxyPlotEquivalent); } // If we change the graph to a box plot then the several unused properties should be disabled. // These are x variable dropdown, x cumulative, x on top, marker size/type checkboxes. // First, make sure that these options are sensitive to input and can be changed. Assert.IsTrue(seriesView.X.IsSensitive); Assert.IsTrue(seriesView.XCumulative.IsSensitive); Assert.IsTrue(seriesView.XOnTop.IsSensitive); Assert.IsTrue(seriesView.MarkerSize.IsSensitive); Assert.IsTrue(seriesView.MarkerType.IsSensitive); // Now change series type to box plot. GtkUtilities.SelectComboBoxItem(seriesView.SeriesType, "Box", wait: true); Assert.AreEqual(SeriesType.Box, series.Type); // Ensure the box plot is not white in light theme. plot = ReflectionUtilities.GetValueOfFieldOrProperty("plot1", view) as PlotView; Assert.NotNull(plot); BoxPlotSeries boxPlot = plot.Model.Series.OfType <BoxPlotSeries>().FirstOrDefault(); Assert.NotNull(boxPlot); Assert.AreNotEqual(empty, boxPlot.Fill); Assert.AreNotEqual(white, boxPlot.Fill); Assert.AreNotEqual(empty, boxPlot.Stroke); Assert.AreNotEqual(white, boxPlot.Stroke); // The controls should no longer be sensitive. Assert.IsFalse(seriesView.XCumulative.IsSensitive); Assert.IsFalse(seriesView.XOnTop.IsSensitive); Assert.IsFalse(seriesView.MarkerSize.IsSensitive); Assert.IsFalse(seriesView.MarkerType.IsSensitive); // Change the series type back to scatter. GtkUtilities.SelectComboBoxItem(seriesView.SeriesType, "Scatter", wait: true); // The controls should be sensitive once more. Assert.IsTrue(seriesView.X.IsSensitive); Assert.IsTrue(seriesView.XCumulative.IsSensitive); Assert.IsTrue(seriesView.XOnTop.IsSensitive); Assert.IsTrue(seriesView.MarkerSize.IsSensitive); Assert.IsTrue(seriesView.MarkerType.IsSensitive); }
public void Initialise() { Simulations basicFile = Utilities.GetRunnableSim(); IModel simulation = Apsim.Find(basicFile, typeof(Simulation)); IModel paddock = Apsim.Find(basicFile, typeof(Zone)); // Add a weather component. Models.Weather weather = new Models.Weather(); weather.Name = "Weather"; weather.FileName = "asdf.met"; Structure.Add(weather, simulation); // Add a second weather component. Models.Weather weather2 = new Models.Weather(); weather2.FileName = "asdf.met"; weather2.Name = "Weather2"; Structure.Add(weather2, simulation); // Add a third weather component. Models.Weather weather3 = new Models.Weather(); weather3.FileName = "asdf.met"; weather3.Name = "Weather3"; Structure.Add(weather3, simulation); // Add a third weather component. Models.Weather weather4 = new Models.Weather(); weather4.FileName = "asdf.met"; weather4.Name = "Weather4"; Structure.Add(weather4, simulation); // Add a report. Models.Report report = new Models.Report(); report.Name = "Report"; Structure.Add(report, paddock); // Add the wheat model. string json = ReflectionUtilities.GetResourceAsString(typeof(IModel).Assembly, "Models.Resources.Wheat.json"); Plant wheat = FileFormat.ReadFromString <IModel>(json, out _).Children[0] as Plant; wheat.ResourceName = "Wheat"; Structure.Add(wheat, paddock); Manager manager = new Manager(); manager.Code = @"using Models.PMF; using Models.Core; using System; namespace Models { [Serializable] public class Script : Model { [Description(""an amount"")] public double Amount { get; set; } } }"; Structure.Add(manager, paddock); Physical physical = new Physical(); physical.BD = new double[5]; physical.AirDry = new double[5]; physical.LL15 = new double[5]; Structure.Add(physical, paddock); basicFile.Write(basicFile.FileName); fileName = basicFile.FileName; // Create a new .apsimx file containing two weather nodes. Simulations test = Utilities.GetRunnableSim(); IModel sim = Apsim.Find(test, typeof(Simulation)); Models.Weather w1 = new Models.Weather(); w1.FileName = "w1.met"; w1.Name = "w1"; Structure.Add(w1, sim); Models.Weather w2 = new Models.Weather(); w2.Name = "w2"; w2.FileName = "w2.met"; Structure.Add(w2, sim); extFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".apsimx"); test.Write(extFile); }
public void TestEditOption() { string[] changes = new string[] { "[Clock].StartDate = 2019-1-20", ".Simulations.Sim1.Clock.EndDate = 3/20/2019", ".Simulations.Sim2.Enabled = false", ".Simulations.Sim1.Field.Soil.Thickness[1] = 500", ".Simulations.Sim1.Field.Soil.Thickness[2] = 2500", ".Simulations.Sim2.Name = SimulationVariant35", }; string configFileName = Path.GetTempFileName(); File.WriteAllLines(configFileName, changes); string apsimxFileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); string text = ReflectionUtilities.GetResourceAsString("UnitTests.BasicFile.apsimx"); // Check property values at this point. Simulations sims = FileFormat.ReadFromString <Simulations>(text, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw errors[0]; } Clock clock = sims.FindInScope <Clock>(); Simulation sim1 = sims.FindInScope <Simulation>(); Simulation sim2 = sims.FindInScope("Sim2") as Simulation; Soil soil = sims.FindByPath(".Simulations.Sim1.Field.Soil")?.Value as Soil; // Check property values - they should be unchanged at this point. DateTime start = new DateTime(2003, 11, 15); Assert.AreEqual(start.Year, clock.StartDate.Year); Assert.AreEqual(start.DayOfYear, clock.StartDate.DayOfYear); Assert.AreEqual(sim1.Name, "Sim1"); Assert.AreEqual(sim2.Enabled, true); Assert.AreEqual(soil.Thickness[0], 150); Assert.AreEqual(soil.Thickness[1], 150); // Run Models.exe with /Edit command. sims.Write(apsimxFileName); Utilities.RunModels($"{apsimxFileName} /Edit {configFileName}"); sims = FileFormat.ReadFromFile <Simulations>(apsimxFileName, out errors); if (errors != null && errors.Count > 0) { throw errors[0]; } // Get references to the changed models. clock = sims.FindInScope <Clock>(); Clock clock2 = sims.FindByPath(".Simulations.SimulationVariant35.Clock")?.Value as Clock; // Sims should have at least 3 children - data store and the 2 sims. Assert.That(sims.Children.Count > 2); sim1 = sims.Children.OfType <Simulation>().First(); sim2 = sims.Children.OfType <Simulation>().Last(); soil = sims.FindByPath(".Simulations.Sim1.Field.Soil")?.Value as Soil; start = new DateTime(2019, 1, 20); DateTime end = new DateTime(2019, 3, 20); // Check clock. Assert.AreEqual(clock.StartDate.Year, start.Year); Assert.AreEqual(clock.StartDate.DayOfYear, start.DayOfYear); Assert.AreEqual(clock.EndDate.Year, end.Year); Assert.AreEqual(clock.EndDate.DayOfYear, end.DayOfYear); // These changes should not affect the clock in simulation 2. start = new DateTime(2003, 11, 15); end = new DateTime(2003, 11, 15); Assert.AreEqual(clock2.StartDate.Year, start.Year); Assert.AreEqual(clock2.StartDate.DayOfYear, start.DayOfYear); Assert.AreEqual(clock2.EndDate.Year, end.Year); Assert.AreEqual(clock2.EndDate.DayOfYear, end.DayOfYear); // Sim2 should have been renamed to SimulationVariant35 Assert.AreEqual(sim2.Name, "SimulationVariant35"); // Sim1's name should be unchanged. Assert.AreEqual(sim1.Name, "Sim1"); // Sim2 should have been disabled. This should not affect sim1. Assert.That(sim1.Enabled); Assert.That(!sim2.Enabled); // First 2 soil thicknesses have been changed to 500 and 2500 respectively. Assert.AreEqual(soil.Thickness[0], 500, 1e-8); Assert.AreEqual(soil.Thickness[1], 2500, 1e-8); }
public void TestSimNameRegex() { string models = typeof(IModel).Assembly.Location; IModel sim1 = Utilities.GetRunnableSim().Children[1]; sim1.Name = "sim1"; IModel sim2 = Utilities.GetRunnableSim().Children[1]; sim2.Name = "sim2"; IModel sim3 = Utilities.GetRunnableSim().Children[1]; sim3.Name = "simulation3"; IModel sim4 = Utilities.GetRunnableSim().Children[1]; sim4.Name = "Base"; Simulations sims = Simulations.Create(new[] { sim1, sim2, sim3, sim4, new DataStore() }); sims.ParentAllDescendants(); string apsimxFileName = Path.ChangeExtension(Path.GetTempFileName(), ".apsimx"); sims.Write(apsimxFileName); // Need to quote the regex on unix systems. string args; if (ProcessUtilities.CurrentOS.IsWindows) { args = $@"{apsimxFileName} /Verbose /SimulationNameRegexPattern:sim\d"; } else { args = $@"{apsimxFileName} /Verbose '/SimulationNameRegexPattern:sim\d'"; } ProcessUtilities.ProcessWithRedirectedOutput proc = new ProcessUtilities.ProcessWithRedirectedOutput(); proc.Start(models, args, Directory.GetCurrentDirectory(), true); proc.WaitForExit(); Assert.Null(proc.StdErr); Assert.True(proc.StdOut.Contains("sim1")); Assert.True(proc.StdOut.Contains("sim2")); Assert.False(proc.StdOut.Contains("simulation3")); Assert.False(proc.StdOut.Contains("Base")); args = $@"{apsimxFileName} /Verbose /SimulationNameRegexPattern:sim1"; proc = new ProcessUtilities.ProcessWithRedirectedOutput(); proc.Start(models, args, Directory.GetCurrentDirectory(), true); proc.WaitForExit(); Assert.Null(proc.StdErr); Assert.True(proc.StdOut.Contains("sim1")); Assert.False(proc.StdOut.Contains("sim2")); Assert.False(proc.StdOut.Contains("simulation3")); Assert.False(proc.StdOut.Contains("Base")); args = $@"{apsimxFileName} /Verbose /SimulationNameRegexPattern:(simulation3)|(Base)"; proc = new ProcessUtilities.ProcessWithRedirectedOutput(); proc.Start(models, args, Directory.GetCurrentDirectory(), true); proc.WaitForExit(); Assert.Null(proc.StdErr); Assert.False(proc.StdOut.Contains("sim1")); Assert.False(proc.StdOut.Contains("sim2")); Assert.True(proc.StdOut.Contains("simulation3")); Assert.True(proc.StdOut.Contains("Base")); }
/// <summary> /// Edits a single apsimx file according to the changes specified in the config file. /// </summary> /// <param name="apsimxFileName">Path to an .apsimx file.</param> /// <param name="factors">Factors to apply to the file.</param> private static void EditFile(string apsimxFileName, List <CompositeFactor> factors) { Simulations file = FileFormat.ReadFromFile <Simulations>(fileName, out List <Exception> errors); if (errors != null && errors.Count > 0) { throw new Exception($"Error reading file ${apsimxFileName}: {errors[0].ToString()}"); } foreach (CompositeFactor factor in factors) { IVariable variable = Apsim.GetVariableObject(file, factor.Paths[0]); if (variable == null) { throw new Exception($"Invalid path: {factor.Paths[0]}"); } string value = factor.Values[0].ToString(); string absolutePath; try { absolutePath = PathUtilities.GetAbsolutePath(value, Directory.GetCurrentDirectory()); } catch { absolutePath = null; } string[] parts = value.Split(';'); if (parts != null && parts.Length == 2) { string fileName = parts[0]; string absoluteFileName = PathUtilities.GetAbsolutePath(fileName, Directory.GetCurrentDirectory()); string modelPath = parts[1]; if (File.Exists(fileName)) { ReplaceModelFromFile(file, factor.Paths[0], fileName, modelPath); } else if (File.Exists(absoluteFileName)) { ReplaceModelFromFile(file, factor.Paths[0], absoluteFileName, modelPath); } else { variable.Value = ReflectionUtilities.StringToObject(variable.DataType, value); } } else if (File.Exists(value) && variable.Value is IModel) { ReplaceModelFromFile(file, factor.Paths[0], value, null); } else if (File.Exists(absolutePath) && variable.Value is IModel) { ReplaceModelFromFile(file, factor.Paths[0], absolutePath, null); } else { variable.Value = ReflectionUtilities.StringToObject(variable.DataType, value); } } file.Write(apsimxFileName); }