def test_old_beforeChild(self): def before(node, child): if type(child) in nonpyomo_leaf_types \ or not child.is_expression_type(): return False, [child] os = StringIO() with LoggingIntercept(os, 'pyomo'): walker = StreamBasedExpressionVisitor(beforeChild=before) self.assertIn( "Note that the API for the StreamBasedExpressionVisitor " "has changed to include the child index for the beforeChild() " "method", os.getvalue().replace('\n', ' ')) ans = walker.walk_expression(self.e) m = self.m ref = [[[m.x], [2]], [m.y], [[m.z], [[m.x], [m.y]]]] self.assertEqual(str(ans), str(ref)) ans = walker.walk_expression(m.x) ref = [] self.assertEqual(str(ans), str(ref)) ans = walker.walk_expression(2) ref = [] self.assertEqual(str(ans), str(ref))
def run_solverfactory_test(): skip_solvers = { 'py', 'xpress', '_xpress_shell', '_mock_xpress', } with LoggingIntercept() as LOG, capture_output(capture_fd=True) as OUT: info = [] for solver in sorted(pyo.SolverFactory): _doc = pyo.SolverFactory.doc(solver) if _doc is not None and 'DEPRECATED' in _doc: _avail = 'DEPR' elif solver in skip_solvers: _avail = 'SKIP' else: _avail = str(pyo.SolverFactory(solver).available(False)) info.append(" %s(%s): %s" % (solver, _avail, _doc)) #_check_log_and_out(LOG, OUT, 20, solver) glpk = pyo.SolverFactory('glpk') print("") print("Pyomo Solvers") print("-------------") print("\n".join(info)) if type(glpk.available(False)) != bool: print("Solver glpk.available() did not return bool") sys.exit(3) _check_log_and_out(LOG, OUT, 20)
def test_scip_solve_from_instance_options(self): # Creating a dummy scip.set file in the cwd # will cover the code that prints a warning _cwd = os.getcwd() tmpdir = TempfileManager.create_tempdir() try: os.chdir(tmpdir) open(join(tmpdir, 'scip.set'), "w").close() # Test scip solve from a pyomo instance and load the solution with LoggingIntercept() as LOG: results = self.scip.solve(self.model, suffixes=['.*'], options={"limits/softtime": 100}) self.assertRegex( LOG.getvalue().replace("\n", " "), r"A file named (.*) exists in the current working " r"directory, but SCIP options are being " r"set using a separate options file. The " r"options file \1 will be ignored.") finally: os.chdir(_cwd) # We don't want the test to care about which Scip version we are using self.model.solutions.store_to(results) results.Solution(0).Message = "Scip" results.Solver.Message = "Scip" results.Solver.Time = 0 _out = TempfileManager.create_tempfile(".txt") results.write(filename=_out, times=False, format='json') self.compare_json( _out, join(currdir, "test_scip_solve_from_instance.baseline"))
def test_log_active_constraints(self): """Test for logging of active constraints.""" m = self.build_model() depr = StringIO() output = StringIO() with LoggingIntercept(depr, 'pyomo.util', logging.WARNING): log_active_constraints(m) self.assertIn("log_active_constraints is deprecated.", depr.getvalue()) with LoggingIntercept(output, 'pyomo.util', logging.INFO): log_active_constraints(m) expected_output = [ "c1 active", "c2 active", "c3 active", "c4 active", "c5 active", "c6 active", "c7 active", "c8 active", "c9 active", "c11 active" ] self.assertEqual(expected_output, output.getvalue()[len(depr.getvalue()):].splitlines())
def test_report_timing(self): # Create a set to ensure that the global sets have already been # constructed (this is an issue until the new set system is # merged in and the GlobalSet objects are not automatically # created by pyomo.core m = ConcreteModel() m.x = Var([1, 2]) ref = """ 0 seconds to construct Block ConcreteModel; 1 index total 0 seconds to construct RangeSet FiniteSimpleRangeSet; 1 index total 0 seconds to construct Var x; 2 indicies total """.strip() os = StringIO() try: report_timing(os) m = ConcreteModel() m.r = RangeSet(2) m.x = Var(m.r) self.assertEqual(os.getvalue().strip(), ref) finally: report_timing(False) buf = StringIO() with LoggingIntercept(buf, 'pyomo'): m = ConcreteModel() m.r = RangeSet(2) m.x = Var(m.r) self.assertEqual(os.getvalue().strip(), ref) self.assertEqual(buf.getvalue().strip(), "")
def test_log_model_constraints(self): m = ConcreteModel() m.x = Var(initialize=1) m.c1 = Constraint(expr=m.x >= 2) m.c2 = Constraint(expr=m.x == 4) m.c3 = Constraint(expr=m.x <= 0) m.y = Var(bounds=(0, 2), initialize=1.9999999) m.c4 = Constraint(expr=m.y >= m.y.value) m.z = Var(bounds=(0, 6)) m.c5 = Constraint(expr=inequality(5, m.z, 10), doc="Range infeasible") m.c6 = Constraint(expr=m.x + m.y <= 6, doc="Feasible") m.c7 = Constraint(expr=m.z == 6, doc="Equality infeasible") m.c8 = Constraint(expr=inequality(3, m.x, 6), doc="Range lb infeasible") m.c9 = Constraint(expr=inequality(0, m.x, 0.5), doc="Range ub infeasible") m.c10 = Constraint(expr=m.y >= 3, doc="Inactive") m.c10.deactivate() m.c11 = Constraint(expr=m.y <= m.y.value) m.yy = Var(bounds=(0, 1), initialize=1E-7, doc="Close to lower bound") m.y3 = Var(bounds=(0, 1E-7), initialize=0, doc="Bounds too close") m.y4 = Var(bounds=(0, 1), initialize=2, doc="Fixed out of bounds.") m.y4.fix() output = StringIO() with LoggingIntercept(output, 'pyomo.util', logging.INFO): log_model_constraints(m) expected_output = [ "c1 active", "c2 active", "c3 active", "c4 active", "c5 active", "c6 active", "c7 active", "c8 active", "c9 active", "c11 active" ] self.assertEqual(expected_output, output.getvalue().splitlines())
def test_example2(self): # Check the log contents log_OUTPUT = StringIO() # Check the printed contents print_OUTPUT = StringIO() sys.stdout = print_OUTPUT with LoggingIntercept(log_OUTPUT, 'pyomo.contrib.trustregion', logging.INFO): example2.main() sys.stdout = sys.__stdout__ # Check the number of iterations - which should be 70ish, but not 80 self.assertIn('Iteration 0', log_OUTPUT.getvalue()) self.assertIn('Iteration 70', log_OUTPUT.getvalue()) self.assertNotIn('Iteration 85', log_OUTPUT.getvalue()) # This had all three step-types, so all three should be present self.assertIn('theta-type step', log_OUTPUT.getvalue()) self.assertIn('f-type step', log_OUTPUT.getvalue()) self.assertIn('step rejected', log_OUTPUT.getvalue()) # These two pieces of information are only printed, not logged self.assertNotIn('EXIT: Optimal solution found.', log_OUTPUT.getvalue()) self.assertNotIn('None : True : 48.383116936949', log_OUTPUT.getvalue()) # All of this should be printed self.assertIn('Iteration 0', print_OUTPUT.getvalue()) self.assertIn('Iteration 70', print_OUTPUT.getvalue()) self.assertNotIn('Iteration 85', print_OUTPUT.getvalue()) self.assertIn('theta-type step', print_OUTPUT.getvalue()) self.assertIn('f-type step', print_OUTPUT.getvalue()) self.assertIn('step rejected', print_OUTPUT.getvalue()) self.assertIn('EXIT: Optimal solution found.', print_OUTPUT.getvalue()) self.assertIn('None : True : 48.383116936949', print_OUTPUT.getvalue())
def test_example1(self): # Check the log contents log_OUTPUT = StringIO() # Check the printed contents print_OUTPUT = StringIO() sys.stdout = print_OUTPUT with LoggingIntercept(log_OUTPUT, 'pyomo.contrib.trustregion', logging.INFO): example1.main() sys.stdout = sys.__stdout__ # Check number of iterations - which should be 4 total self.assertIn('Iteration 0', log_OUTPUT.getvalue()) self.assertIn('Iteration 4', log_OUTPUT.getvalue()) self.assertNotIn('Iteration 5', log_OUTPUT.getvalue()) # There were only theta-type steps in this self.assertIn('theta-type step', log_OUTPUT.getvalue()) self.assertNotIn('f-type step', log_OUTPUT.getvalue()) # These two pieces of information are only printed, not logged self.assertNotIn('EXIT: Optimal solution found.', log_OUTPUT.getvalue()) self.assertNotIn('None : True : 0.2770447887637415', log_OUTPUT.getvalue()) # All of this should be printed self.assertIn('Iteration 0', print_OUTPUT.getvalue()) self.assertIn('Iteration 4', print_OUTPUT.getvalue()) self.assertNotIn('Iteration 5', print_OUTPUT.getvalue()) self.assertIn('theta-type step', print_OUTPUT.getvalue()) self.assertNotIn('f-type step', print_OUTPUT.getvalue()) self.assertIn('EXIT: Optimal solution found.', print_OUTPUT.getvalue()) self.assertIn('None : True : 0.2770447887637415', print_OUTPUT.getvalue())
def test_OLD_beforeChild_acceptChildResult_afterChild(self): counts = [0,0,0] def before(node, child): counts[0] += 1 if type(child) in nonpyomo_leaf_types \ or not child.is_expression_type(): return False, None def accept(node, data, child_result): counts[1] += 1 def after(node, child): counts[2] += 1 os = StringIO() with LoggingIntercept(os, 'pyomo'): walker = StreamBasedExpressionVisitor( beforeChild=before, acceptChildResult=accept, afterChild=after) self.assertIn( "Note that the API for the StreamBasedExpressionVisitor " "has changed to include the child index for the " "beforeChild() method", os.getvalue().replace('\n',' ')) self.assertIn( "Note that the API for the StreamBasedExpressionVisitor " "has changed to include the child index for the " "acceptChildResult() method", os.getvalue().replace('\n',' ')) self.assertIn( "Note that the API for the StreamBasedExpressionVisitor " "has changed to include the child index for the " "afterChild() method", os.getvalue().replace('\n',' ')) ans = walker.walk_expression(self.e) m = self.m self.assertEqual(ans, None) self.assertEqual(counts, [9,9,9])
def test_update_block_derived_override_construct_nofcn2(self): class Foo(Block): def construct(self, data=None): Block.construct(self, data) m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.s = Set(initialize=[1, 2, 3]) def _block_rule(b, t, s): m = b.model() def _init(m, j): return j * 2 b.p1 = Param(m.t, default=_init) b.v1 = Var(m.t, initialize=5) m.foo = Foo(m.t, m.s, rule=_block_rule) generate_finite_elements(m.t, 5) OUTPUT = StringIO() with LoggingIntercept(OUTPUT, 'pyomo.dae'): expand_components(m) self.assertIn('transformation to the Block-derived component', OUTPUT.getvalue()) self.assertEqual(len(m.foo), 18) self.assertEqual(len(m.foo[0, 1].p1), 6) self.assertEqual(len(m.foo[2, 2].v1), 6) self.assertEqual(m.foo[0, 3].p1[6], 12)
def test_open_tempfile_windows(self): TempfileManager.push() fname = TempfileManager.create_tempfile() f = open(fname) try: _orig = tempfiles.deletion_errors_are_fatal tempfiles.deletion_errors_are_fatal = True with self.assertRaisesRegex( WindowsError, ".*process cannot access the file"): TempfileManager.pop() finally: tempfiles.deletion_errors_are_fatal = _orig f.close() os.remove(fname) TempfileManager.push() fname = TempfileManager.create_tempfile() f = open(fname) log = StringIO() try: _orig = tempfiles.deletion_errors_are_fatal tempfiles.deletion_errors_are_fatal = False with LoggingIntercept(log, 'pyomo.common'): TempfileManager.pop() self.assertIn("Unable to delete temporary file", log.getvalue()) finally: tempfiles.deletion_errors_are_fatal = _orig f.close() os.remove(fname)
def test_log_active_constraints(self): """Test for logging of active constraints.""" m = self.build_model() output = StringIO() with LoggingIntercept(output, 'pyomo.util.infeasible', logging.INFO): log_active_constraints(m) expected_output = ["c active", "c2 active", "c3 active", "c4 active"] self.assertEqual(output.getvalue().splitlines(), expected_output)
def test_tempfilecontext_as_context_manager(self): with LoggingIntercept() as LOG: ctx = self.TM.new_context() with ctx: fname = ctx.create_tempfile() self.assertTrue(os.path.exists(fname)) self.assertFalse(os.path.exists(fname)) self.assertEqual(LOG.getvalue(), "")
def test_log_close_to_bounds(self): """Test logging of variables and constraints near bounds.""" m = self.build_model() output = StringIO() with LoggingIntercept(output, 'pyomo.util.infeasible', logging.INFO): log_close_to_bounds(m) expected_output = ["y near UB of 2", "c4 near LB"] self.assertEqual(output.getvalue().splitlines(), expected_output)
def test_find_component_deprecated(self): ref = self.m.b[1, '2'].c.a[3] cuid = ComponentUID(ref) DEP_OUT = StringIO() with LoggingIntercept(DEP_OUT, 'pyomo.core'): self.assertTrue(cuid.find_component(self.m) is ref) self.assertIn('ComponentUID.find_component() is deprecated.', DEP_OUT.getvalue())
def test_bound_function(self): if multiprocessing.get_start_method() == 'fork': self.bound_function() return LOG = six.StringIO() with LoggingIntercept(LOG): with self.assertRaises(TypeError): self.bound_function() self.assertIn("platform that does not support 'fork'", LOG.getvalue())
def test_no_objective(self): m = ConcreteModel() m.x = Var(bounds=(-5, 5)) m.c = Constraint(expr=m.x ** 2 >= 1) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING): SolverFactory('gdpopt').solve(m, nlp_solver=nlp_solver, strategy='LOA') self.assertIn("Model has no active objectives. Adding dummy objective.", output.getvalue().strip())
def test_overwrite_warning(self): c = self._container_type() out = StringIO() with LoggingIntercept(out, 'pyomo.core'): c.append(self._ctype_factory()) c[0] = c[0] assert out.getvalue() == "" with LoggingIntercept(out, 'pyomo.core'): c[0] = self._ctype_factory() assert out.getvalue() == \ ("Implicitly replacing the entry [0] " "(type=%s) with a new object (type=%s). " "This is usually indicative of a modeling " "error. To avoid this warning, delete the " "original object from the container before " "assigning a new object.\n" % (self._ctype_factory().__class__.__name__, self._ctype_factory().__class__.__name__))
def test_err_for_bogus_kwds(self): m = self.makeModel() OUTPUT = StringIO() with LoggingIntercept(OUTPUT, 'pyomo.core'): TransformationFactory('core.add_slack_variables').apply_to( m, notakwd="I want a feasible model") self.assertIn( "Unrecognized keyword arguments in add slack variable " "transformation:\nnotakwd", OUTPUT.getvalue())
def test_cyipopt_callbacks(self): ex = import_file( os.path.join(example_dir, 'callback', 'cyipopt_callback.py')) output = StringIO() with LoggingIntercept(output, 'pyomo', logging.INFO): ex.main() self.assertIn("Residuals for iteration 2", output.getvalue().strip())
def test_deprecation_warning(self): DEP_OUT = StringIO() with LoggingIntercept(DEP_OUT, 'pyomo'): deprecation_warning(None, version='1.2', remove_in='3.4') self.assertIn('DEPRECATED: This has been deprecated', DEP_OUT.getvalue()) self.assertIn('(deprecated in 1.2, will be removed in (or after) 3.4)', DEP_OUT.getvalue().replace('\n',' ')) DEP_OUT = StringIO() with LoggingIntercept(DEP_OUT, 'pyomo'): deprecation_warning("custom message here", version='1.2', remove_in='3.4') self.assertIn('DEPRECATED: custom message here', DEP_OUT.getvalue()) self.assertIn('(deprecated in 1.2, will be removed in (or after) 3.4)', DEP_OUT.getvalue().replace('\n',' '))
def test_pickle(self): m = ConcreteModel() m.x = Var(units=units.kg) m.c = Constraint(expr=m.x**2 <= 10*units.kg**2) log = StringIO() with LoggingIntercept(log, 'pyomo.core.base'): i = pickle.loads(pickle.dumps(m)) self.assertEqual("", log.getvalue()) self.assertIsNot(m.x, i.x) self.assertIsNot(m.x._units, i.x._units) self.assertEqual(m.x._units, i.x._units) self.assertEqual(str(m.c.upper), str(i.c.upper)) base = StringIO() m.pprint(base) test = StringIO() i.pprint(test) self.assertEqual(base.getvalue(), test.getvalue()) # Test pickling a custom units manager um = PyomoUnitsContainer() m = ConcreteModel() m.x = Var(units=um.kg) m.c = Constraint(expr=m.x**2 <= 10*um.kg**2) log = StringIO() with LoggingIntercept(log, 'pyomo.core.base'): i = pickle.loads(pickle.dumps(m)) self.assertIn( "pickling a _PyomoUnit associated with a PyomoUnitsContainer " "that is not the default singleton " "(pyomo.core.base.units_container.units)", log.getvalue()) self.assertIsNot(m.x, i.x) self.assertIsNot(m.x._units, i.x._units) # Note that pint is inconsistent when comparing standard units # across different UnitRegistry instances: older versions of # pint would have them compare "not equal" while newer versions # compare equal # # self.assertNotEqual(m.x._units, i.x._units) self.assertEqual(str(m.c.upper), str(i.c.upper)) base = StringIO() m.pprint(base) test = StringIO() i.pprint(test) self.assertEqual(base.getvalue(), test.getvalue())
def test_report_timing(self): # Create a set to ensure that the global sets have already been # constructed (this is an issue until the new set system is # merged in and the GlobalSet objects are not automatically # created by pyomo.core m = ConcreteModel() m.x = Var([1,2]) ref = r""" (0(\.\d+)?) seconds to construct Block ConcreteModel; 1 index total (0(\.\d+)?) seconds to construct RangeSet FiniteSimpleRangeSet; 1 index total (0(\.\d+)?) seconds to construct Var x; 2 indices total (0(\.\d+)?) seconds to construct Suffix Suffix; 1 index total (0(\.\d+)?) seconds to apply Transformation RelaxIntegerVars \(in-place\) """.strip() xfrm = TransformationFactory('core.relax_integer_vars') try: with capture_output() as out: report_timing() m = ConcreteModel() m.r = RangeSet(2) m.x = Var(m.r) xfrm.apply_to(m) result = out.getvalue().strip() self.maxDiff = None for l, r in zip(result.splitlines(), ref.splitlines()): self.assertRegex(str(l.strip()), str(r.strip())) finally: report_timing(False) os = StringIO() try: report_timing(os) m = ConcreteModel() m.r = RangeSet(2) m.x = Var(m.r) xfrm.apply_to(m) result = os.getvalue().strip() self.maxDiff = None for l, r in zip(result.splitlines(), ref.splitlines()): self.assertRegex(str(l.strip()), str(r.strip())) finally: report_timing(False) buf = StringIO() with LoggingIntercept(buf, 'pyomo'): m = ConcreteModel() m.r = RangeSet(2) m.x = Var(m.r) xfrm.apply_to(m) result = os.getvalue().strip() self.maxDiff = None for l, r in zip(result.splitlines(), ref.splitlines()): self.assertRegex(str(l.strip()), str(r.strip())) self.assertEqual(buf.getvalue().strip(), "")
def test_log_infeasible_bounds(self): """Test for logging of infeasible variable bounds.""" m = self.build_model() m.x.setlb(2) m.x.setub(0) output = StringIO() with LoggingIntercept(output, 'pyomo.util.infeasible', logging.INFO): log_infeasible_bounds(m) expected_output = ["VAR x: 1 < LB 2", "VAR x: 1 > UB 0"] self.assertEqual(expected_output, output.getvalue().splitlines())
def test_deprecated_ComponentUID_location(self): import pyomo.core.base.component as comp self.assertNotIn('ComponentUID', dir(comp)) warning = "DEPRECATED: the 'ComponentUID' class has been moved to " \ "'pyomo.core.base.componentuid.ComponentUID'" OUT = StringIO() with LoggingIntercept(OUT, 'pyomo.core'): from pyomo.core.base.component import ComponentUID \ as old_ComponentUID self.assertIn(warning, OUT.getvalue().replace('\n', ' ')) self.assertIs(old_ComponentUID, ComponentUID) self.assertIs(old_ComponentUID, ComponentUID) OUT = StringIO() with LoggingIntercept(OUT, 'pyomo.core'): self.assertIs(comp.ComponentUID, ComponentUID) self.assertEqual("", OUT.getvalue())
def test_missing_bounds(self): m = ConcreteModel() m.x = Var(domain=NonNegativeReals) m.obj = Objective(expr=m.x) output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.multistart', logging.WARNING): SolverFactory('multistart').solve(m) self.assertIn("Unable to reinitialize value of unbounded " "variable x with bounds (0, None).", output.getvalue().strip())
def test_no_integer(self): m = ConcreteModel() m.x = Var() output = StringIO() with LoggingIntercept(output, 'pyomo.contrib.preprocessing', logging.INFO): xfrm('contrib.integer_to_binary').apply_to(m) expected_message = "Model has no free integer variables." self.assertIn(expected_message, output.getvalue())
def test_with_custom_logger(self): @deprecated('This is a custom message', logger='local', version='test') def foo(bar='yeah'): """Show that I am a good person. Because I document my public functions. """ logger.warning(bar) self.assertIn( '.. deprecated:: test\n This is a custom message', foo.__doc__) self.assertIn('I am a good person.', foo.__doc__) # Test the default argument DEP_OUT = StringIO() FCN_OUT = StringIO() with LoggingIntercept(DEP_OUT, 'pyomo'): with LoggingIntercept(FCN_OUT, 'local'): foo() # Test that the function produces output self.assertIn('yeah', FCN_OUT.getvalue()) self.assertIn('DEPRECATED: This is a custom message', FCN_OUT.getvalue()) # Test that the deprecation warning was logged self.assertNotIn('DEPRECATED:', DEP_OUT.getvalue()) # Test that the function argument gets passed in DEP_OUT = StringIO() FCN_OUT = StringIO() with LoggingIntercept(DEP_OUT, 'pyomo'): with LoggingIntercept(FCN_OUT, 'local'): foo("custom") # Test that the function produces output self.assertNotIn('yeah', FCN_OUT.getvalue()) self.assertIn('custom', FCN_OUT.getvalue()) self.assertIn('DEPRECATED: This is a custom message', FCN_OUT.getvalue()) # Test that the deprecation warning was logged self.assertNotIn('DEPRECATED:', DEP_OUT.getvalue())
def test_initialized_continuous_set(self): m = ConcreteModel() m.t = ContinuousSet(initialize=[0, 1, 2, 3, 4]) m.v = Var(m.t) m.dv = DerivativeVar(m.v) log_out = StringIO() with LoggingIntercept(log_out, 'pyomo.dae'): TransformationFactory('dae.collocation').apply_to(m, nfe=2) self.assertIn('More finite elements', log_out.getvalue())
def test_unknown_library(self): m = ConcreteModel() with LoggingIntercept() as LOG: m.ef = ExternalFunction( library='unknown_pyomo_external_testing_function', function='f') self.assertEqual( LOG.getvalue(), 'Defining AMPL external function, but cannot locate ' 'specified library "unknown_pyomo_external_testing_function"\n')