• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

blue-marble / gridpath / 14431500873

09 Apr 2025 10:33PM UTC coverage: 89.009%. Remained the same
14431500873

push

github

anamileva
Catch empty cursor description

26562 of 29842 relevant lines covered (89.01%)

2.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.05
/tests/test_examples.py
1
# Copyright 2016-2023 Blue Marble Analytics LLC.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#     http://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14

15
import ast
3✔
16
import csv
3✔
17
import logging
3✔
18
import multiprocessing
3✔
19
import os
3✔
20
import pandas as pd
3✔
21
import platform
3✔
22
import sqlite3
3✔
23
import unittest
3✔
24

25
from gridpath import run_end_to_end, run_scenario, validate_inputs
3✔
26
from db import create_database
3✔
27
from db.common_functions import connect_to_database
3✔
28
from db.utilities import port_csvs_to_db, scenario
3✔
29

30
# Change directory to 'gridpath' directory, as that's what run_scenario.py
31
# expects; the rest of the global variables are relative paths from there
32
os.chdir(os.path.join(os.path.dirname(__file__), "..", "gridpath"))
3✔
33
EXAMPLES_DIRECTORY = os.path.join("..", "examples")
3✔
34
DB_NAME = "unittest_examples"
3✔
35
DB_PATH = f"../db/{DB_NAME}.db"
3✔
36
DB_SCHEMA = f"../db/db_schema.sql"
3✔
37
DATA_DIRECTORY = "../db/data"
3✔
38
CSV_PATH = "../db//csvs_test_examples"
3✔
39
SCENARIOS_CSV = os.path.join(CSV_PATH, "scenarios.csv")
3✔
40
TEST_SCENARIOS_CSV = "../tests/test_data/test_scenario_objective_function_values.csv"
3✔
41

42
# Platform check
43
LINUX = True if platform.system() == "Linux" else False
3✔
44
MACOS = True if platform.system() == "Darwin" else False
3✔
45
WINDOWS = True if platform.system() == "Windows" else False
3✔
46

47

48
class TestExamples(unittest.TestCase):
3✔
49
    """ """
50

51
    df = pd.read_csv(TEST_SCENARIOS_CSV, delimiter=",")
3✔
52
    df.set_index("test_scenario", inplace=True)
3✔
53

54
    def assertDictAlmostEqual(self, d1, d2, msg=None, places=7):
3✔
55
        # check if both inputs are dicts
56
        self.assertIsInstance(d1, dict, "First argument is not a dictionary")
3✔
57
        self.assertIsInstance(d2, dict, "Second argument is not a dictionary")
3✔
58

59
        # check if both inputs have the same keys
60
        self.assertEqual(d1.keys(), d2.keys())
3✔
61

62
        # check each key
63
        for key, value in d1.items():
3✔
64
            if isinstance(value, dict):
3✔
65
                self.assertDictAlmostEqual(d1[key], d2[key], places=places, msg=msg)
3✔
66
            else:
67
                self.assertAlmostEqual(d1[key], d2[key], places=places, msg=msg)
3✔
68

69
    def check_validation(self, test):
3✔
70
        """
71
        Check that validate inputs runs without errors, and that there
72
        are no validation issues recorded in the status_validation table
73
        :return:
74
        """
75

76
        # Check that test validation runs without errors
77
        validate_inputs.main(["--database", DB_PATH, "--scenario", test, "--quiet"])
3✔
78

79
        # Check that no validation issues are recorded in the db for the test
80
        expected_validations = []
3✔
81

82
        conn = connect_to_database(
3✔
83
            db_path=DB_PATH, detect_types=sqlite3.PARSE_DECLTYPES
84
        )
85
        c = conn.cursor()
3✔
86
        validations = c.execute(
3✔
87
            """
88
            SELECT scenario_name FROM status_validation
89
            INNER JOIN
90
            (SELECT scenario_id, scenario_name FROM scenarios)
91
            USING (scenario_id)
92
            WHERE scenario_name = '{}'
93
            """.format(
94
                test
95
            )
96
        )
97
        actual_validations = validations.fetchall()
3✔
98

99
        self.assertListEqual(expected_validations, actual_validations)
3✔
100

101
    def run_and_check_objective(
3✔
102
        self, test, expected_objective, solver=None, parallel=1
103
    ):
104
        """
105

106
        :param test: str, name of the test example
107
        :param expected_objective: float or dict, expected objective
108
        :param parallel: int, set to a number > 1 to test
109
            parallelization functionality
110
        :return:
111
        """
112
        args_to_pass = [
3✔
113
            "--database",
114
            DB_PATH,
115
            "--scenario",
116
            test,
117
            "--scenario_location",
118
            EXAMPLES_DIRECTORY,
119
            # "--log",
120
            # "--write_solver_files_to_logs_dir",
121
            # "--keepfiles",
122
            # "--symbolic",
123
            "--n_parallel_get_inputs",
124
            str(parallel),
125
            "--n_parallel_solve",
126
            str(parallel),
127
            "--quiet",
128
            "--mute_solver_output",
129
            "--testing",
130
        ]
131
        if solver is not None:
3✔
132
            args_to_pass.append("--solver")
×
133
            args_to_pass.append(solver)
×
134

135
        actual_objective = run_end_to_end.main(args_to_pass)
3✔
136

137
        # Check if we have a multiprocessing manager
138
        # If so, convert the manager proxy dictionary to a simple dictionary
139
        # to avoid errors
140
        # Done via copies to avoid broken pipe error
141
        if hasattr(multiprocessing, "managers"):
3✔
142
            if isinstance(actual_objective, multiprocessing.managers.DictProxy):
3✔
143
                # Make a dictionary from a copy of the objective
144
                actual_objective_copy = dict(actual_objective.copy())
×
145
                for subproblem in actual_objective.keys():
×
146
                    # If we have stages, make a dictionary form a copy of the
147
                    # stage dictionary for each subproblem
148
                    if isinstance(
×
149
                        actual_objective[subproblem], multiprocessing.managers.DictProxy
150
                    ):
151
                        stage_dict_copy = dict(actual_objective_copy[subproblem].copy())
×
152
                        # Reset the stage dictionary to the new simple
153
                        # dictionary object
154
                        actual_objective_copy[subproblem] = stage_dict_copy
×
155
                # Reset the objective to the new dictionary object
156
                actual_objective = actual_objective_copy
×
157

158
        # Uncomment this to save new objective function values
159
        df = pd.read_csv(TEST_SCENARIOS_CSV, delimiter=",")
3✔
160
        df.set_index("test_scenario", inplace=True)
3✔
161
        # Set dtype to 'object' so that we can have floats and dictionaries
162
        # in the column
163
        df["actual_objective"] = df["actual_objective"].astype("object")
3✔
164
        df.at[test, "actual_objective"] = actual_objective
3✔
165
        df.to_csv(TEST_SCENARIOS_CSV, index=True)
3✔
166

167
        # Multi-subproblem and/or multi-stage scenarios return dict
168
        if isinstance(expected_objective, dict):
3✔
169
            self.assertDictAlmostEqual(expected_objective, actual_objective, places=1)
3✔
170
        # Otherwise, objective is a single value
171
        else:
172
            self.assertAlmostEqual(expected_objective, actual_objective, places=1)
×
173

174
    @classmethod
3✔
175
    def setUpClass(cls):
3✔
176
        """
177
        Set up the testing database
178
        :return:
179
        """
180

181
        if os.path.exists(DB_PATH):
3✔
182
            os.remove(DB_PATH)
×
183

184
        create_database.main(
3✔
185
            [
186
                "--database",
187
                DB_PATH,
188
                "--db_schema",
189
                DB_SCHEMA,
190
                "--data_directory",
191
                DATA_DIRECTORY,
192
            ]
193
        )
194

195
        try:
3✔
196
            port_csvs_to_db.main(
3✔
197
                ["--database", DB_PATH, "--csv_location", CSV_PATH, "--quiet"]
198
            )
199
        except Exception as e:
×
200
            print(
×
201
                "Error encountered during population of testing database "
202
                "{}.db. Deleting database ...".format(DB_NAME)
203
            )
204
            logging.exception(e)
×
205
            os.remove(DB_PATH)
×
206

207
        try:
3✔
208
            scenario.main(
3✔
209
                ["--database", DB_PATH, "--csv_path", SCENARIOS_CSV, "--quiet"]
210
            )
211
        except Exception as e:
×
212
            print(
×
213
                "Error encountered during population of testing database "
214
                "{}.db. Deleting database ...".format(DB_NAME)
215
            )
216
            logging.exception(e)
×
217
            os.remove(DB_PATH)
×
218

219
    def validate_and_test_example_generic(
3✔
220
        self, scenario_name, solver=None, skip_validation=False
221
    ):
222
        # Use the expected objective column by default
223
        column_to_use = "expected_objective"
3✔
224
        if MACOS and not pd.isnull(
3✔
225
            self.df.loc[scenario_name]["expected_objective_darwin"]
226
        ):
227
            column_to_use = "expected_objective_darwin"
×
228
        if WINDOWS and not pd.isnull(
3✔
229
            self.df.loc[scenario_name]["expected_objective_windows"]
230
        ):
231
            column_to_use = "expected_objective_windows"
×
232

233
        # Evaluate the objective function as a literal (as it is in
234
        # dictionary format stored as string in the CSV)
235
        # This is now done for all scenarios, even if they have no iterations
236
        # or multiple subproblem/stages
237
        objective = ast.literal_eval(self.df.loc[scenario_name][column_to_use])
3✔
238
        if not skip_validation:
3✔
239
            self.check_validation(scenario_name)
3✔
240
        self.run_and_check_objective(
3✔
241
            test=scenario_name, solver=solver, expected_objective=objective
242
        )
243

244
    def test_example_test(self):
3✔
245
        """
246
        Check validation and objective function value of "test" example
247
        :return:
248
        """
249
        scenario_name = "test"
3✔
250
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
251

252
    def test_example_test_no_overgen_allowed(self):
3✔
253
        """
254
        Check validation and objective function value of
255
        "test_no_overgen_allowed" example
256
        :return:
257
        """
258

259
        scenario_name = "test_no_overgen_allowed"
3✔
260
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
261

262
    def test_example_test_new_build_storage(self):
3✔
263
        """
264
        Check validation and objective function value of
265
        "test_new_build_storage" example
266
        :return:
267
        """
268

269
        scenario_name = "test_new_build_storage"
3✔
270
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
271

272
    def test_example_test_new_binary_build_storage(self):
3✔
273
        """
274
        Check validation and objective function value of
275
        "test_new_binary_build_storage" example
276
        :return:
277
        """
278
        scenario_name = "test_new_binary_build_storage"
3✔
279
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
280

281
    def test_example_test_new_build_storage_cumulative_min_max(self):
3✔
282
        """
283
        Check validation and objective function value of
284
        "test_new_build_storage_cumulative_min_max" example
285
        :return:
286
        """
287
        scenario_name = "test_new_build_storage_cumulative_min_max"
3✔
288
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
289

290
    def test_example_test_no_reserves(self):
3✔
291
        """
292
        Check validation and objective function value of
293
        "test_no_reserves" example
294
        :return:
295
        """
296
        scenario_name = "test_no_reserves"
3✔
297
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
298

299
    def test_example_test_w_hydro(self):
3✔
300
        """
301
        Check validation and objective function value of "test_w_hydro" example
302
        :return:
303
        """
304
        scenario_name = "test_w_hydro"
3✔
305
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
306

307
    def test_example_test_w_storage(self):
3✔
308
        """
309
        Check validation and objective function value of "test_w_storage" example
310
        :return:
311
        """
312
        scenario_name = "test_w_storage"
3✔
313
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
314

315
    def test_example_2horizons(self):
3✔
316
        """
317
        Check validation and objective function value of "2horizons" example
318
        :return:
319
        """
320
        scenario_name = "2horizons"
3✔
321
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
322

323
    def test_example_2horizons_w_hydro(self):
3✔
324
        """
325
        Check validation and objective function value of
326
        "2horizons_w_hydro" example
327
        :return:
328
        """
329
        scenario_name = "2horizons_w_hydro"
3✔
330
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
331

332
    def test_example_2horizons_w_hydro_and_nuclear_binary_availability(self):
3✔
333
        """
334
        Check validation and objective function value of
335
        "2horizons_w_hydro_and_nuclear_binary_availability" example
336

337
        NOTE: the objective function for this example is lower than that for
338
        the '2horizons_w_hydro' example because of the unrealistically high
339
        relative heat rate of the 'Nuclear' project relative to the gas
340
        projects; allowing binary availability for a must-run project
341
        actually allows lower-cost power when the nuclear plant is
342
        unavailable. We should probably re-think this example as part of a
343
        future more general revamp of the examples.
344

345
        :return:
346
        """
347
        scenario_name = "2horizons_w_hydro_and_nuclear_binary_availability"
3✔
348
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
349

350
    def test_example_2horizons_w_hydro_w_balancing_types(self):
3✔
351
        """
352
        Check validation and objective function value of
353
        "2horizons_w_hydro_w_balancing_types" example. The objective
354
        function of this example should be lower than that of the
355
        '2horizons_w_hydro' example, as the average hydro budget is the
356
        same across all timepoints, but the hydro balancing horizon is now
357
        longer.
358
        :return:
359
        """
360
        scenario_name = "2horizons_w_hydro_w_balancing_types"
3✔
361
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
362

363
    def test_example_2periods(self):
3✔
364
        """
365
        Check validation and objective function value of "2periods" example
366
        :return:
367
        """
368
        scenario_name = "2periods"
3✔
369
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
370

371
    def test_example_2periods_new_build(self):
3✔
372
        """
373
        Check validation and objective function value of "2periods_new_build" example
374
        """
375
        scenario_name = "2periods_new_build"
3✔
376
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
377

378
    def test_example_2periods_new_build_2zones(self):
3✔
379
        """
380
        Check validation and objective function value of
381
        "2periods_new_build_2zones" example
382
        :return:
383
        """
384
        scenario_name = "2periods_new_build_2zones"
3✔
385
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
386

387
    def test_example_2periods_new_build_2zones_new_build_transmission(self):
3✔
388
        """
389
        Check validation and objective function value of
390
        "2periods_new_build_2zones_new_build_transmission" example
391
        :return:
392
        """
393
        scenario_name = "2periods_new_build_2zones_new_build_transmission"
3✔
394
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
395

396
    def test_example_2periods_new_build_2zones_singleBA(self):
3✔
397
        """
398
        Check validation and objective function value of
399
        "2periods_new_build_2zones_singleBA"
400
        example
401
        :return:
402
        """
403
        scenario_name = "2periods_new_build_2zones_singleBA"
3✔
404
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
405

406
    def test_example_2periods_new_build_2zones_transmission(self):
3✔
407
        """
408
        Check validation and objective function value of
409
        "2periods_new_build_2zones_transmission" example
410
        :return:
411
        """
412
        scenario_name = "2periods_new_build_2zones_transmission"
3✔
413
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
414

415
    def test_example_2periods_new_build_2zones_transmission_w_losses(self):
3✔
416
        """
417
        Check validation and objective function value of
418
        "2periods_new_build_2zones_transmission_w_losses" example
419
        :return:
420
        """
421
        scenario_name = "2periods_new_build_2zones_transmission_w_losses"
3✔
422
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
423

424
    def test_example_2periods_new_build_2zones_transmission_w_losses_opp_dir(self):
3✔
425
        """
426
        Check validation and objective function value of
427
        "2periods_new_build_2zones_transmission_w_losses_opp_dir" example
428

429
        Note: this should be the same as the objective function for
430
        2periods_new_build_2zones_transmission_w_losses
431
        :return:
432
        """
433
        scenario_name = "2periods_new_build_2zones_transmission_w_losses_opp_dir"
3✔
434
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
435

436
    def test_example_2periods_new_build_rps(self):
3✔
437
        """
438
        Check validation and objective function value of
439
        "2periods_new_build_rps" example
440
        :return:
441
        """
442
        scenario_name = "2periods_new_build_rps"
3✔
443
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
444

445
    def test_example_2periods_new_build_rps_percent_target(self):
3✔
446
        """
447
        Check objective function value of
448
        "2periods_new_build_rps_percent_target" example
449
        This example should have the same objective function as
450
        test_example_2periods_new_build_rps, as its target is the same,
451
        but specified as percentage of load.
452
        :return:
453
        """
454
        scenario_name = "2periods_new_build_rps_percent_target"
3✔
455
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
456

457
    def test_example_2periods_new_build_cumulative_min_max(self):
3✔
458
        """
459
        Check validation and objective function value of
460
        "2periods_new_build_cumulative_min_max" example
461
        :return:
462
        """
463
        scenario_name = "2periods_new_build_cumulative_min_max"
3✔
464
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
465

466
    def test_example_single_stage_prod_cost(self):
3✔
467
        """
468
        Check validation and objective function values of
469
        "single_stage_prod_cost" example
470
        :return:
471
        """
472
        scenario_name = "single_stage_prod_cost"
3✔
473
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
474

475
    def test_example_single_stage_prod_cost_linked_subproblems(self):
3✔
476
        """
477
        Check objective function values of
478
        "single_stage_prod_cost_linked_subproblems" example
479
        :return:
480
        """
481
        scenario_name = "single_stage_prod_cost_linked_subproblems"
3✔
482
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
483

484
    def test_example_single_stage_prod_cost_linked_subproblems_w_hydro(self):
3✔
485
        """
486
        Check objective function values of
487
        "single_stage_prod_cost_linked_subproblems" example
488
        :return:
489
        """
490
        scenario_name = "single_stage_prod_cost_linked_subproblems_w_hydro"
3✔
491
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
492

493
    def test_example_multi_stage_prod_cost(self):
3✔
494
        """
495
        Check validation and objective function values of
496
        "multi_stage_prod_cost" example
497
        :return:
498
        """
499
        scenario_name = "multi_stage_prod_cost"
3✔
500
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
501

502
    def test_example_single_stage_prod_cost_cycle_select(self):
3✔
503
        """
504
        Check validation and objective function values of
505
        "single_stage_prod_cost_cycle_select" example. This example is the same as
506
        single_stage_prod_cost but the Coal and Gas_CCGT plants have mutually
507
        exclusive commitment in this example.
508
        """
509
        scenario_name = "single_stage_prod_cost_cycle_select"
3✔
510
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
511

512
    def test_example_multi_stage_prod_cost_parallel(self):
3✔
513
        """
514
        Check "multi_stage_prod_cost" example running subproblems in parallel
515
        (getting inputs and optimization)
516
        :return:
517
        """
518
        run_end_to_end.main(
3✔
519
            [
520
                "--database",
521
                DB_PATH,
522
                "--scenario",
523
                "multi_stage_prod_cost",
524
                "--scenario_location",
525
                EXAMPLES_DIRECTORY,
526
                # "--log",
527
                # "--write_solver_files_to_logs_dir",
528
                # "--keepfiles",
529
                # "--symbolic",
530
                "--n_parallel_get_inputs",
531
                "3",
532
                "--n_parallel_solve",
533
                "3",
534
                "--quiet",
535
                "--mute_solver_output",
536
                "--testing",
537
            ]
538
        )
539

540
    def test_example_multi_stage_prod_cost_w_hydro(self):
3✔
541
        """
542
        Check validation and objective function values of
543
        "multi_stage_prod_cost_w_hydro"
544
        example
545
        :return:
546
        """
547
        scenario_name = "multi_stage_prod_cost_w_hydro"
3✔
548
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
549

550
    def test_example_multi_stage_prod_cost_linked_subproblems(self):
3✔
551
        """
552
        Check validation and objective function values of
553
        "multi_stage_prod_cost_linked_subproblems" example
554
        :return:
555
        """
556
        scenario_name = "multi_stage_prod_cost_linked_subproblems"
3✔
557
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
558

559
    def test_example_2periods_gen_lin_econ_retirement(self):
3✔
560
        """
561
        Check validation and objective function value of
562
        "2periods_gen_lin_econ_retirement"
563
        example
564
        :return:
565
        """
566
        scenario_name = "2periods_gen_lin_econ_retirement"
3✔
567
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
568

569
    def test_example_2periods_gen_bin_econ_retirement(self):
3✔
570
        """
571
        Check validation and objective function value of
572
        "2periods_gen_bin_econ_retirement"
573
        example
574
        :return:
575
        """
576
        scenario_name = "2periods_gen_bin_econ_retirement"
3✔
577
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
578

579
    def test_example_variable_gen_reserves(self):
3✔
580
        """
581
        Check validation and objective function value of
582
        "variable_gen_reserves"
583
        example; this example requires a non-linear solver
584
        :return:
585
        """
586
        scenario_name = "test_variable_gen_reserves"
3✔
587
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
588

589
    def test_example_2periods_new_build_rps_variable_reserves(self):
3✔
590
        """
591
        Check validation and objective function value of
592
        "2periods_new_build_rps_variable_reserves" example
593
        :return:
594
        """
595
        scenario_name = "2periods_new_build_rps_variable_reserves"
3✔
596
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
597

598
    def test_example_2periods_new_build_rps_variable_reserves_subhourly_adj(self):
3✔
599
        """
600
        Check validation and objective function value of
601
        "2periods_new_build_rps_variable_reserves_subhourly_adj" example
602
        :return:
603
        """
604
        scenario_name = "2periods_new_build_rps_variable_reserves_subhourly_adj"
3✔
605
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
606

607
    def test_example_test_ramp_up_constraints(self):
3✔
608
        """
609
        Check validation and objective function value of
610
        "test_ramp_up_constraints" example
611
        :return:
612
        """
613
        scenario_name = "test_ramp_up_constraints"
3✔
614
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
615

616
    def test_example_test_ramp_up_and_down_constraints(self):
3✔
617
        """
618
        Check validation and objective function value of
619
        "test_ramp_up_and_down_constraints"
620
        example;
621
        :return:
622
        """
623
        scenario_name = "test_ramp_up_and_down_constraints"
3✔
624
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
625

626
    def test_example_2periods_new_build_rps_w_rps_ineligible_storage(self):
3✔
627
        """
628
        Check validation and objective function value of
629
        "2periods_new_build_rps_w_rps_ineligible_storage" example
630
        :return:
631
        """
632
        scenario_name = "2periods_new_build_rps_w_rps_ineligible_storage"
3✔
633
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
634

635
    def test_example_2periods_new_build_rps_w_rps_eligible_storage(self):
3✔
636
        """
637
        Check validation and objective function value of
638
        "2periods_new_build_rps_w_rps_eligible_storage" example
639
        :return:
640
        """
641
        scenario_name = "2periods_new_build_rps_w_rps_eligible_storage"
3✔
642
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
643

644
    def test_example_test_new_solar(self):
3✔
645
        """
646
        Check validation and objective function value of
647
        "test_new_solar" example
648
        :return:
649
        """
650
        scenario_name = "test_new_solar"
3✔
651
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
652

653
    def test_example_test_new_binary_solar(self):
3✔
654
        """
655
        Check validation and objective function value of
656
        "test_new_binary_solar" example
657
        :return:
658
        """
659
        scenario_name = "test_new_binary_solar"
3✔
660
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
661

662
    def test_example_test_new_solar_carbon_cap(self):
3✔
663
        """
664
        Check validation and objective function value of
665
        "test_new_solar_carbon_cap" example
666
        :return:
667
        """
668
        scenario_name = "test_new_solar_carbon_cap"
3✔
669
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
670

671
    def test_example_test_new_solar_carbon_cap_2zones_tx(self):
3✔
672
        """
673
        Check validation and objective function value of
674
        "test_new_solar_carbon_cap_2zones_tx" example
675
        :return:
676
        """
677
        scenario_name = "test_new_solar_carbon_cap_2zones_tx"
3✔
678
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
679

680
    def test_example_test_new_solar_carbon_cap_2zones_dont_count_tx(self):
3✔
681
        """
682
        Check validation and objective function value of
683
        "test_new_solar_carbon_cap_2zones_dont_count_tx" example
684
        :return:
685
        """
686
        scenario_name = "test_new_solar_carbon_cap_2zones_dont_count_tx"
3✔
687
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
688

689
    def test_example_test_new_solar_carbon_tax(self):
3✔
690
        """
691
        Check validation and objective function value of
692
        "test_new_solar_carbon_tax" example
693
        :return:
694
        """
695
        scenario_name = "test_new_solar_carbon_tax"
3✔
696
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
697

698
    def test_example_2periods_new_build_simple_prm(self):
3✔
699
        """
700
        Check validation and objective function value of
701
        "2periods_new_build_simple_prm"
702
        example
703
        :return:
704
        """
705
        scenario_name = "2periods_new_build_simple_prm"
3✔
706
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
707

708
    def test_example_2periods_new_build_simple_prm_w_energy_only(self):
3✔
709
        """
710
        Check validation and objective function value of
711
        "2periods_new_build_simple_prm"
712
        example
713
        :return:
714
        """
715
        scenario_name = "2periods_new_build_simple_prm_w_energy_only"
3✔
716
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
717

718
    def test_example_2periods_new_build_simple_prm_w_energy_only_deliv_cap_limit(self):
3✔
719
        """
720
        Check validation and objective function value of
721
        "2periods_new_build_simple_prm"
722
        example
723
        :return:
724
        """
725
        scenario_name = "2periods_new_build_simple_prm_w_energy_only_deliv_cap_limit"
3✔
726
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
727

728
    def test_example_2periods_new_build_local_capacity(self):
3✔
729
        """
730
        Check validation and objective function value of
731
        "2periods_new_build_local_capacity"
732
        example
733
        :return:
734
        """
735
        scenario_name = "2periods_new_build_local_capacity"
3✔
736
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
737

738
    def test_example_test_tx_dcopf(self):
3✔
739
        """
740
        Check validation and objective function value of
741
        "test_tx_dcopf" example
742
        :return:
743
        """
744
        scenario_name = "test_tx_dcopf"
3✔
745
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
746

747
    def test_example_test_tx_simple(self):
3✔
748
        """
749
        Check validation and objective function value of
750
        "test_tx_simple" example
751
        :return:
752
        """
753
        scenario_name = "test_tx_simple"
3✔
754
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
755

756
    def test_example_test_startup_shutdown_rates(self):
3✔
757
        """
758
        Check validation and objective function value of
759
        "test_startup_shutdown_rates"
760
        example
761
        :return:
762
        """
763
        scenario_name = "test_startup_shutdown_rates"
3✔
764
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
765

766
    def test_no_fuels(self):
3✔
767
        """
768
        Check validation and objective function value of "test_no_fuels"
769
        example
770
        :return:
771
        """
772
        scenario_name = "test_no_fuels"
3✔
773
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
774

775
    def test_variable_om_curves(self):
3✔
776
        """
777
        Check validation and objective function value of
778
        "test_variable_om_curves"
779
        example
780
        :return:
781
        """
782
        scenario_name = "test_variable_om_curves"
3✔
783
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
784

785
    def test_aux_cons(self):
3✔
786
        """
787
        Check validation and objective function value of
788
        "test_aux_cons" example
789

790
        Note: the objective function value is lower than that for the "test"
791
        example because the auxiliary consumption results in less
792
        overgeneration and therefore lower overgeneration penalty.
793
        """
794
        scenario_name = "test_aux_cons"
3✔
795
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
796

797
    def test_example_test_w_lf_down_percent_req(self):
3✔
798
        """
799
        Check validation and objective function value of
800
        "test_w_lf_down_percent_req" example
801
        :return:
802
        """
803
        scenario_name = "test_w_lf_down_percent_req"
3✔
804
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
805

806
    def test_example_2periods_new_build_capgroups(self):
3✔
807
        """
808
        Check validation and objective function value of
809
        "test_example_2periods_new_build_capgroups" example
810
        """
811
        scenario_name = "2periods_new_build_capgroups"
3✔
812
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
813

814
    def test_example_test_markets(self):
3✔
815
        """
816
        Check validation and objective function value of "test" example
817
        :return:
818
        """
819
        scenario_name = "test_markets"
3✔
820
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
821

822
    def test_example_2periods_new_build_horizon_energy_target(self):
3✔
823
        """
824
        Check validation and objective function value of
825
        "test_example_2periods_new_build_horizon_energy_target" example
826
        :return:
827
        """
828
        scenario_name = "2periods_new_build_horizon_energy_target"
3✔
829
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
830

831
    def test_example_2periods_new_build_horizon_energy_target_halfyear(self):
3✔
832
        """
833
        Check validation and objective function value of
834
        "2periods_new_build_horizon_energy_target_halfyear" example
835
        :return:
836
        """
837
        scenario_name = "2periods_new_build_horizon_energy_target_halfyear"
3✔
838
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
839

840
    def test_example_test_new_build_gen_var_stor_hyb(self):
3✔
841
        """
842
        Check validation and objective function value of
843
        "test_new_build_gen_var_stor_hyb" example
844
        :return:
845
        """
846
        scenario_name = "test_new_build_gen_var_stor_hyb"
3✔
847
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
848

849
    def test_example_test_carbon_tax_allowance(self):
3✔
850
        """
851
        Check validation and objective function value of
852
        "test_carbon_tax_allowance" example
853
        :return:
854
        """
855
        scenario_name = "test_carbon_tax_allowance"
3✔
856
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
857

858
    def test_example_test_min_max_build_trans(self):
3✔
859
        """
860
        Check validation and objective function value of
861
        "test_min_max_build_trans" example
862
        :return:
863
        """
864
        scenario_name = "test_min_max_build_trans"
3✔
865
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
866

867
    def test_example_2periods_new_build_2zones_transmission_Tx1halfavail(self):
3✔
868
        """
869
        Check validation and objective function value of
870
        "2periods_new_build_2zones_transmission_Tx1halfavail" example
871
        :return:
872
        """
873
        scenario_name = "2periods_new_build_2zones_transmission_Tx1halfavail"
3✔
874
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
875

876
    def test_example_2periods_new_build_2zones_transmission_Tx1halfavailmonthly(self):
3✔
877
        """
878
        Check validation and objective function value of
879
        "2periods_new_build_2zones_transmission_Tx1halfavail" example
880
        :return:
881
        """
882
        scenario_name = "2periods_new_build_2zones_transmission_Tx1halfavailmonthly"
3✔
883
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
884

885
    def test_example_test_cheap_fuel_blend(self):
3✔
886
        """
887
        Check validation and objective function value of "test_cheap_fuel_blend" example
888
        :return:
889
        """
890
        scenario_name = "test_cheap_fuel_blend"
3✔
891
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
892

893
    def test_example_test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend(self):
3✔
894
        """
895
        Check validation and objective function value of
896
        "test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend" example
897
        :return:
898
        """
899
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend"
3✔
900
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
901

902
    def test_example_test_cheap_fuel_blend_w_limit(self):
3✔
903
        """
904
        Check validation and objective function value of
905
        "test_cheap_fuel_blend_w_limit" example
906
        :return:
907
        """
908
        scenario_name = "test_cheap_fuel_blend_w_limit"
3✔
909
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
910

911
    def test_example_test_new_solar_fuel_burn_limit(self):
3✔
912
        """
913
        Check validation and objective function value of
914
        "test_new_solar_fuel_burn_limit" example. Inputs set up so that this should
915
        be the same as the "test_new_solar_carbon_cap" example.
916
        :return:
917
        """
918
        scenario_name = "test_new_solar_fuel_burn_limit"
3✔
919
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
920

921
    def test_example_test_new_solar_fuel_burn_limit_relative(self):
3✔
922
        """
923
        Check validation and objective function value of
924
        "test_new_solar_fuel_burn_limit_relative" example. Inputs set up so that this
925
        should be the same as the "test_new_solar_fuel_burn_limit" example.
926
        :return:
927
        """
928
        scenario_name = "test_new_solar_fuel_burn_limit_relative"
3✔
929
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
930

931
    def test_test_w_solver_options(self):
3✔
932
        """
933
        Check validation and objective function value of "test_w_solver_options" example
934
        :return:
935
        """
936
        scenario_name = "test_w_solver_options"
3✔
937
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
938

939
    def test_example_test_carbon_tax_allowance_with_different_fuel_groups(self):
3✔
940
        """
941
        Check validation and objective function value of
942
        "test_carbon_tax_allowance_with_different_fuel_groups" example
943
        :return:
944
        """
945
        scenario_name = "test_carbon_tax_allowance_with_different_fuel_groups"
3✔
946
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
947

948
    def test_performance_standard(self):
3✔
949
        """
950
        Check validation and objective function value of "test_performance_standard" example
951
        :return:
952
        """
953
        scenario_name = "test_performance_standard"
3✔
954
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
955

956
    def test_tx_flow(self):
3✔
957
        """
958
        Check validation and objective function value of
959
        "test_tx_flow" example
960
        :return:
961
        """
962
        scenario_name = "test_tx_flow"
3✔
963
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
964

965
    def test_example_test_new_solar_reserve_prj_contribution(self):
3✔
966
        """
967
        Check validation and objective function value of
968
        "test_reserve_prj_contribution" example.
969
        This example is based on "test_new_solar" with the only difference, the LF UP
970
        requirement ID
971
        :return:
972
        """
973
        scenario_name = "test_new_solar_reserve_prj_contribution"
3✔
974
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
975

976
    def test_test_new_solar_carbon_cap_2zones_tx_hydrogen_prod(self):
3✔
977
        """
978
        Check validation and objective function value of
979
        "test_reserve_prj_contribution" example.
980
        This example is based on "test_new_solar" with the only difference, the LF UP
981
        requirement ID
982
        :return:
983
        """
984
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_hydrogen_prod"
3✔
985
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
986

987
    def test_test_new_solar_carbon_cap_2zones_tx_hydrogen_prod_new(self):
3✔
988
        """
989
        Check validation and objective function value of
990
        "test_reserve_prj_contribution" example.
991
        This example is based on "test_new_solar" with the only difference, the LF UP
992
        requirement ID
993
        :return:
994
        """
995
        scenario_name = "test_new_solar_carbon_cap_2zones_tx_hydrogen_prod_new"
3✔
996
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
997

998
    def test_example_test_new_solar_carbon_cap_dac(self):
3✔
999
        """
1000
        Check validation and objective function value of
1001
        "test_new_solar_carbon_cap_dac" example.
1002

1003
        Note that the same version of Cbc (v2.10.5) produces a slightly different
1004
        objective function for this problem on Windows than on Mac.
1005
        :return:
1006
        """
1007
        scenario_name = "test_new_solar_carbon_cap_dac"
3✔
1008
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1009

1010
    def test_example_test_cap_factor_limits(self):
3✔
1011
        """
1012
        Check validation and objective function value of "test" example
1013
        :return:
1014
        """
1015
        scenario_name = "test_cap_factor_limits"
3✔
1016
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1017

1018
    def test_example_multi_stage_prod_cost_w_markets(self):
3✔
1019
        """
1020
        Check validation and objective function values of
1021
        "multi_stage_prod_cost_w_markets" example
1022
        :return:
1023
        """
1024
        scenario_name = "multi_stage_prod_cost_w_markets"
3✔
1025
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1026

1027
    def test_example_test_supplemental_firing(self):
3✔
1028
        """
1029
        Check validation and objective function value of "test_supplemental_firing" example
1030
        :return:
1031
        """
1032
        scenario_name = "test_supplemental_firing"
3✔
1033
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1034

1035
    def test_example_test_tx_capacity_groups(self):
3✔
1036
        """
1037
        Check validation and objective function value of
1038
        "test_tx_capacity_groups" example
1039
        :return:
1040
        """
1041
        scenario_name = "test_tx_capacity_groups"
3✔
1042
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1043

1044
    def test_example_2periods_new_build_fin_lifetime(self):
3✔
1045
        """
1046
        Check validation and objective function value of
1047
        "2periods_new_build_fin_lifetime" example. Same as "2periods_new_build" but
1048
        with shorter financial lifetimes and some fixed costs. Cost is lower because
1049
        the same payment is made fewer times.
1050
        """
1051
        scenario_name = "2periods_new_build_fin_lifetime"
3✔
1052
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1053

1054
    def test_example_2periods_new_build_cumulative_and_vintage_min_max(self):
3✔
1055
        """
1056
        Check validation and objective function value of
1057
        "2periods_new_build_cumulative_and_vintage_min_max" example. It is the same
1058
        as 2periods_new_build_cumulative_and_min_max but with a max in 2020 for the
1059
        CCGT to force early build and a min on the CT in 2030 to force more build.
1060

1061
        :return:
1062
        """
1063
        scenario_name = "2periods_new_build_cumulative_and_vintage_min_max"
3✔
1064
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1065

1066
    def test_example_test_w_storage_w_soc_penalty(self):
3✔
1067
        """
1068
        Check validation and objective function value of "test_w_storage_w_soc_penalty"
1069
        example
1070
        :return:
1071
        """
1072
        scenario_name = "test_w_storage_w_soc_penalty"
3✔
1073
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1074

1075
    def test_example_test_w_storage_w_soc_last_tmp_penalty(self):
3✔
1076
        """
1077
        Check validation and objective function value of "test_w_storage_w_soc_penalty"
1078
        example
1079
        :return:
1080
        """
1081
        scenario_name = "test_w_storage_w_soc_last_tmp_penalty"
3✔
1082
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1083

1084
    def test_example_test_new_solar_itc(self):
3✔
1085
        """
1086
        Check validation and objective function value of
1087
        "test_new_solar_itc" example
1088
        :return:
1089
        """
1090
        scenario_name = "test_new_solar_itc"
3✔
1091
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1092

1093
    def test_example_test_new_build_storage_itc(self):
3✔
1094
        """
1095
        Check validation and objective function value of
1096
        "test_new_build_storage" example
1097
        :return:
1098
        """
1099
        scenario_name = "test_new_build_storage_itc"
3✔
1100
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1101

1102
    def test_example_2periods_new_build_simple_prm_2loadzones(self):
3✔
1103
        """
1104
        Check validation and objective function value of
1105
        "2periods_new_build_simple_prm_2loadzones"
1106
        example
1107
        :return:
1108
        """
1109
        scenario_name = "2periods_new_build_simple_prm_2loadzones"
3✔
1110
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1111

1112
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers(self):
3✔
1113
        """
1114
        Check validation and objective function value of
1115
        "2periods_new_build_simple_prm_w_transfers"
1116
        example
1117
        :return:
1118
        """
1119
        scenario_name = "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers"
3✔
1120
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1121

1122
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs(
3✔
1123
        self,
1124
    ):
1125
        """
1126
        Check validation and objective function value of
1127
        "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs"
1128
        example
1129
        :return:
1130
        """
1131
        scenario_name = (
3✔
1132
            "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_costs"
1133
        )
1134
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1135

1136
    def test_example_test_w_flex_load(self):
3✔
1137
        """
1138
        Check validation and objective function value of "test_w_storage" example
1139
        :return:
1140
        """
1141
        scenario_name = "test_w_flex_load"
3✔
1142
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1143

1144
    def test_example_test_new_solar_w_relative_capacity_instead_of_potential(self):
3✔
1145
        """
1146
        Check validation and objective function value of
1147
        "test_new_solar" example
1148
        :return:
1149
        """
1150
        scenario_name = "test_new_solar_w_relative_capacity_instead_of_potential"
3✔
1151
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1152

1153
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates(self):
3✔
1154
        """
1155
        Check validation and objective function value of
1156
        "2periods_new_build_2zones_transmission_w_hurdle_rates" example
1157
        :return:
1158
        """
1159
        scenario_name = "2periods_new_build_2zones_transmission_w_hurdle_rates"
3✔
1160
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1161

1162
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint(
3✔
1163
        self,
1164
    ):
1165
        """
1166
        Check validation and objective function value of
1167
        "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint" example
1168
        :return:
1169
        """
1170
        scenario_name = (
3✔
1171
            "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint"
1172
        )
1173
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1174

1175
    def test_example_2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period(
3✔
1176
        self,
1177
    ):
1178
        """
1179
        Check validation and objective function value of
1180
        "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period" example
1181
        :return:
1182
        """
1183
        scenario_name = "2periods_new_build_2zones_transmission_w_hurdle_rates_by_timepoint_and_period"
3✔
1184
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1185

1186
    def test_example_2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_subsidies(
3✔
1187
        self,
1188
    ):
1189
        """
1190
        Check validation and objective function value of
1191
        "test_new_solar" example
1192
        :return:
1193
        """
1194
        scenario_name = (
3✔
1195
            "2periods_new_build_simple_prm_2loadzones_newtx_w_transfers_w_subsidies"
1196
        )
1197
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1198

1199
    def test_example_test_new_build_storage_itc_single_superperiod(self):
3✔
1200
        """
1201
        Check validation and objective function value of
1202
        "test_new_build_storage_itc_single_superperiodself" example
1203
        :return:
1204
        """
1205
        scenario_name = "test_new_build_storage_itc_single_superperiod"
3✔
1206
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1207

1208
    def test_incomplete_only(self):
3✔
1209
        """
1210
        Check that the "incomplete only" functionality works with no errors.
1211
        :return:
1212
        """
1213
        actual_objective = run_scenario.main(
3✔
1214
            [
1215
                "--scenario",
1216
                "test",
1217
                "--scenario_location",
1218
                EXAMPLES_DIRECTORY,
1219
                "--quiet",
1220
                "--mute_solver_output",
1221
                "--incomplete_only",
1222
            ]
1223
        )
1224

1225
    def test_example_test_w_storage_starting_soc(self):
3✔
1226
        """
1227
        Check validation and objective function value of
1228
        "test_w_storage_starting_soc" example
1229
        :return:
1230
        """
1231
        scenario_name = "test_w_storage_starting_soc"
3✔
1232
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1233

1234
    def test_example_test_w_nonfuel_emissions(self):
3✔
1235
        """
1236
        Check validation and objective function value of "test" example
1237
        :return:
1238
        """
1239
        scenario_name = "test_w_nonfuel_emissions"
3✔
1240
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1241

1242
    def test_example_test_new_solar_carbon_credits(self):
3✔
1243
        """
1244
        Check validation and objective function value of
1245
        "test_new_solar_carbon_credits" example
1246
        :return:
1247
        """
1248
        scenario_name = "test_new_solar_carbon_credits"
3✔
1249
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1250

1251
    def test_performance_standard_carbon_credits(self):
3✔
1252
        """
1253
        Check validation and objective function value of "test_performance_standard" example
1254
        :return:
1255
        """
1256
        scenario_name = "test_performance_standard_carbon_credits"
3✔
1257
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1258

1259
    def test_example_test_new_solar_carbon_tax_w_carbon_credits(self):
3✔
1260
        """
1261
        Check validation and objective function value of
1262
        "test_new_solar_carbon_tax_w_carbon_credits" example
1263
        :return:
1264
        """
1265
        scenario_name = "test_new_solar_carbon_tax_w_carbon_credits"
3✔
1266
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1267

1268
    def test_example_test_new_solar_carbon_credits_w_sell(self):
3✔
1269
        """
1270
        Check validation and objective function value of
1271
        "test_new_solar_carbon_credits_w_sell" example
1272
        The carbon credit price must be set higher than the cost of USE in this
1273
        example to incentivize the project to not run and generate credits.
1274
        :return:
1275
        """
1276
        scenario_name = "test_new_solar_carbon_credits_w_sell"
3✔
1277
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1278

1279
    def test_test_performance_standard_carbon_credits_w_cap_no_credits_mapping(self):
3✔
1280
        """
1281
        Check validation and objective function value of
1282
        "test_performance_standard_carbon_credits_w_cap_no_credits_mapping" example
1283
        :return:
1284
        """
1285
        scenario_name = (
3✔
1286
            "test_performance_standard_carbon_credits_w_cap_no_credits_mapping"
1287
        )
1288
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1289

1290
    def test_test_new_solar_carbon_credits_w_buy(self):
3✔
1291
        """
1292
        Check validation and objective function value of "test_new_solar_carbon_credits_w_buy" example
1293
        :return:
1294
        """
1295
        scenario_name = "test_new_solar_carbon_credits_w_buy"
3✔
1296
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1297

1298
    def test_test_new_solar_carbon_credits_w_buy_and_sell(self):
3✔
1299
        """
1300
        Check validation and objective function value of "test_new_solar_carbon_credits_w_buy_and_sell" example
1301
        :return:
1302
        """
1303
        scenario_name = "test_new_solar_carbon_credits_w_buy_and_sell"
3✔
1304
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1305

1306
    def test_example_single_stage_prod_cost_w_spinup_lookahead(self):
3✔
1307
        """
1308
        Check validation and objective function values of
1309
        "single_stage_prod_cost_w_spinup_lookahead" example
1310
        :return:
1311
        """
1312
        scenario_name = "single_stage_prod_cost_w_spinup_lookahead"
3✔
1313
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1314

1315
    def test_example_test_tx_targets_max(self):
3✔
1316
        """
1317
        Check validation and objective function value of
1318
        "test_example_test_tx_targets_max"
1319
        example
1320
        :return:
1321
        """
1322
        scenario_name = "test_tx_targets_max"
3✔
1323
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1324

1325
    def test_example_ra_toolkit_monte_carlo(self):
3✔
1326
        """
1327
        Check validation and objective function values of
1328
        "ra_toolkit_monte_carlo" example
1329
        :return:
1330
        """
1331
        scenario_name = "ra_toolkit_monte_carlo"
3✔
1332
        self.validate_and_test_example_generic(
3✔
1333
            scenario_name=scenario_name, skip_validation=True
1334
        )
1335

1336
    def test_example_ra_toolkit_sync(self):
3✔
1337
        """
1338
        Check validation and objective function values of
1339
        "ra_toolkit_sync" example
1340
        :return:
1341
        """
1342
        scenario_name = "ra_toolkit_sync"
3✔
1343
        self.validate_and_test_example_generic(
3✔
1344
            scenario_name=scenario_name, skip_validation=True
1345
        )
1346

1347
    def test_example_2periods_nuclear_var_cost_by_period_same(self):
3✔
1348
        """
1349
        Check validation and objective function value of "2periods_nuclear_var_cost_by_period_same" example
1350
        :return:
1351
        """
1352
        scenario_name = "2periods_nuclear_var_cost_by_period_same"
3✔
1353
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1354

1355
    def test_example_2periods_nuclear_var_cost_by_period_diff(self):
3✔
1356
        """
1357
        Check validation and objective function value of
1358
        "2periods_nuclear_var_cost_by_period_diff" example
1359
        :return:
1360
        """
1361
        scenario_name = "2periods_nuclear_var_cost_by_period_diff"
3✔
1362
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1363

1364
    def test_example_ra_toolkit_sync_single_year(self):
3✔
1365
        """
1366
        Check validation and objective function values of
1367
        "ra_toolkit_sync_single_year" example
1368
        :return:
1369
        """
1370
        scenario_name = "ra_toolkit_sync_single_year"
3✔
1371
        self.validate_and_test_example_generic(
3✔
1372
            scenario_name=scenario_name, skip_validation=True
1373
        )
1374

1375
    def test_test_performance_standard_power(self):
3✔
1376
        """
1377
        Check validation and objective function values of "test_performance_standard_power" example
1378
        :return:
1379
        """
1380
        scenario_name = "test_performance_standard_power"
3✔
1381
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1382

1383
    def test_test_performance_standard_both(self):
3✔
1384
        """
1385
        Check validation and objective function values of "test_performance_standard_both" example
1386
        :return:
1387
        """
1388
        scenario_name = "test_performance_standard_both"
3✔
1389
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1390

1391
    def test_test_new_instantaneous_penetration(self):
3✔
1392
        """
1393
        Check validation and objective function value of "test_new_instantaneous_penetration" example
1394
        :return:
1395
        """
1396

1397
        scenario_name = "test_new_instantaneous_penetration"
3✔
1398
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1399

1400
    def test_hydro_system_exog_elev(self):
3✔
1401
        """
1402
        Check validation and objective function value of "hydro_system" example
1403
        :return:
1404
        """
1405

1406
        scenario_name = "hydro_system_exog_elev"
3✔
1407
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1408

1409
    def test_hydro_system_exog_elev_w_travel_time(self):
3✔
1410
        """
1411
        Check validation and objective function value of "hydro_system" example
1412
        :return:
1413
        """
1414

1415
        scenario_name = "hydro_system_exog_elev_w_travel_time"
3✔
1416
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1417

1418
    def test_test_tx_flow_w_simflow(self):
3✔
1419
        """
1420
        Check validation and objective function value of "test_tx_flow_w_simflow" example
1421
        :return:
1422
        """
1423

1424
        scenario_name = "test_tx_flow_w_simflow"
3✔
1425
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1426

1427
    def test_example_ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile(
3✔
1428
        self,
1429
    ):
1430
        """
1431
        Check validation and objective function values of
1432
        "ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile" example
1433
        :return:
1434
        """
1435
        scenario_name = "ra_toolkit_sync_single_year_w_hydro_instead_of_weather_profile"
3✔
1436
        self.validate_and_test_example_generic(
3✔
1437
            scenario_name=scenario_name, skip_validation=True
1438
        )
1439

1440
    def test_example_2periods_new_build_2zones_loadcomponents(self):
3✔
1441
        """
1442
        Check validation and objective function value of
1443
        "2periods_new_build_2zones_loadcomponents" example
1444
        :return:
1445
        """
1446
        scenario_name = "2periods_new_build_2zones_loadcomponents"
3✔
1447
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1448

1449
    def test_example_2periods_nuclear_var_cost_by_timepoint_same(self):
3✔
1450
        """
1451
        Check validation and objective function value of
1452
        "2periods_nuclear_var_cost_by_timepoint_same" example
1453
        :return:
1454
        """
1455
        scenario_name = "2periods_nuclear_var_cost_by_timepoint_same"
3✔
1456
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1457

1458
    def test_example_2periods_nuclear_var_cost_by_timepoint_diff(self):
3✔
1459
        """
1460
        Check validation and objective function value of
1461
        "2periods_nuclear_var_cost_by_timepoint_diff" example
1462
        :return:
1463
        """
1464
        scenario_name = "2periods_nuclear_var_cost_by_timepoint_diff"
3✔
1465
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1466

1467
    def test_example_test_w_storage_wind_as_energy(self):
3✔
1468
        """
1469
        Check validation and objective function value of
1470
        "test_w_storage_wind_as_energy" example
1471
        :return:
1472
        """
1473
        scenario_name = "test_w_storage_wind_as_energy"
3✔
1474
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1475

1476
    def test_example_test_w_hydro_no_reserves(self):
3✔
1477
        """
1478
        Check validation and objective function value of
1479
        "test_w_hydro_no_reserves"
1480
        example
1481
        :return:
1482
        """
1483
        scenario_name = "test_w_hydro_no_reserves"
3✔
1484
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1485

1486
    def test_example_test_w_hydro_as_energy_no_reserves(self):
3✔
1487
        """
1488
        Check validation and objective function value of
1489
        "test_w_hydro_as_energy_no_reserves"
1490
        example
1491
        :return:
1492
        """
1493
        scenario_name = "test_w_hydro_as_energy_no_reserves"
3✔
1494
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1495

1496
    def test_example_test_w_lf(self):
3✔
1497
        """
1498
        Check validation and objective function value of
1499
        "test_w_lf" example
1500
        :return:
1501
        """
1502
        scenario_name = "test_w_lf"
3✔
1503
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1504

1505
    def test_example_test_w_lf_w_demand_charges(self):
3✔
1506
        """
1507
        Check validation and objective function value of
1508
        "test_w_lf_w_demand_charges" example
1509
        :return:
1510
        """
1511
        scenario_name = "test_w_lf_w_demand_charges"
3✔
1512
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1513

1514
    def test_example_test_w_lf_only(self):
3✔
1515
        """
1516
        Check validation and objective function value of
1517
        "test_w_lf_only" example
1518
        :return:
1519
        """
1520
        scenario_name = "test_w_lf_only"
3✔
1521
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1522

1523
    def test_example_test_w_lf_only_and_prices(self):
3✔
1524
        """
1525
        Check validation and objective function value of
1526
        "test_w_lf_only_and_prices" example
1527
        :return:
1528
        """
1529
        scenario_name = "test_w_lf_only_and_prices"
3✔
1530
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1531

1532
    def test_example_test_w_lf_only_energy_potential_limit(self):
3✔
1533
        """
1534
        Check validation and objective function value of
1535
        "test_w_lf_only_energy_potential_limit" example
1536
        :return:
1537
        """
1538
        scenario_name = "test_w_lf_only_energy_potential_limit"
3✔
1539
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1540

1541
    def test_example_test_w_hydro_as_slice_candidate(self):
3✔
1542
        """
1543
        Check validation and objective function value of
1544
        "test_w_hydro_as_slice_candidate"
1545
        example
1546
        :return:
1547
        """
1548
        scenario_name = "test_w_hydro_as_slice_candidate"
3✔
1549
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1550

1551
    def test_example_test_w_energy_products(self):
3✔
1552
        """
1553
        Check validation and objective function value of
1554
        "test_w_lf_only_and_prices" example
1555
        :return:
1556
        """
1557
        scenario_name = "test_w_energy_products"
3✔
1558
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1559

1560
    def test_example_test_w_energy_products_group_limits(self):
3✔
1561
        """
1562
        Check validation and objective function value of
1563
        "test_w_lf_only_and_prices" example
1564
        :return:
1565
        """
1566
        scenario_name = "test_w_energy_products_group_limits"
3✔
1567
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1568

1569
    def test_example_2periods_new_build_generic_policy(self):
3✔
1570
        """
1571
        Check validation and objective function value of
1572
        "2periods_new_build_generic_policy" example
1573
        :return:
1574
        """
1575
        scenario_name = "2periods_new_build_generic_policy"
3✔
1576
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1577

1578
    def test_open_data(self):
3✔
1579
        """
1580
        Check validation and objective function value of "open_data" example
1581
        :return:
1582
        """
1583

1584
        scenario_name = "open_data"
3✔
1585
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1586

1587
    def test_hydro_system_exog_elev_w_travel_time_and_max_halfday_flows(self):
3✔
1588
        """
1589
        :return:
1590
        """
1591

1592
        scenario_name = "hydro_system_exog_elev_w_travel_time_and_max_halfday_flows"
3✔
1593
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1594

1595
    def test_hydro_system_w_ramp_limits(self):
3✔
1596
        """
1597
        :return:
1598
        """
1599

1600
        scenario_name = "hydro_system_w_ramp_limits"
3✔
1601
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1602

1603
    def test_test_w_bt_hrz_avl(self):
3✔
1604
        """
1605
        :return:
1606
        """
1607

1608
        scenario_name = "test_w_bt_hrz_avl"
3✔
1609
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1610

1611
    def test_hydro_system_exog_elev_w_gen_ramp_limits(self):
3✔
1612
        """ """
1613
        scenario_name = "hydro_system_exog_elev_w_gen_ramp_limits"
3✔
1614
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1615

1616
    def test_dsm_examples(self):
3✔
1617
        scenario_name = "dsm_examples"
3✔
1618
        self.validate_and_test_example_generic(scenario_name=scenario_name)
3✔
1619

1620
    @classmethod
3✔
1621
    def tearDownClass(cls):
3✔
1622
        os.remove(DB_PATH)
3✔
1623
        for temp_file_ext in ["-shm", "-wal"]:
3✔
1624
            temp_file = "{}{}".format(DB_PATH, temp_file_ext)
3✔
1625
            if os.path.exists(temp_file):
3✔
1626
                os.remove(temp_file)
1✔
1627

1628

1629
if __name__ == "__main__":
3✔
1630
    unittest.main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc