| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | from unittest.mock import patch, MagicMock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from wuttaweb.views import upgrades as mod | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | from wuttjamaican.exc import ConfigurationError | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | from wuttaweb.progress import get_progress_session | 
					
						
							| 
									
										
										
										
											2025-01-06 16:47:48 -06:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestUpgradeView(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_view(self): | 
					
						
							|  |  |  |         return mod.UpgradeView(self.request) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_includeme(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.include("wuttaweb.views.upgrades") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_configure_grid(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sanity / coverage check | 
					
						
							|  |  |  |         grid = view.make_grid(model_class=model.Upgrade) | 
					
						
							|  |  |  |         view.configure_grid(grid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_grid_row_class(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  |         upgrade = model.Upgrade(description="test", status=enum.UpgradeStatus.PENDING) | 
					
						
							|  |  |  |         data = dict(upgrade) | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsNone(view.grid_row_class(upgrade, data, 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         upgrade.status = enum.UpgradeStatus.EXECUTING | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             view.grid_row_class(upgrade, data, 1), "has-background-warning" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         upgrade.status = enum.UpgradeStatus.SUCCESS | 
					
						
							|  |  |  |         self.assertIsNone(view.grid_row_class(upgrade, data, 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         upgrade.status = enum.UpgradeStatus.FAILURE | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             view.grid_row_class(upgrade, data, 1), "has-background-warning" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_configure_form(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("upgrades.download", "/upgrades/{uuid}/download") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # some fields exist when viewing | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "viewing", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             form = view.make_form(model_class=model.Upgrade, model_instance=upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("created", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             view.configure_form(form) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("created", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but then are removed when creating | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "creating", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             form = view.make_form(model_class=model.Upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("created", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             view.configure_form(form) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("created", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         # test executed, stdout/stderr when viewing | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "viewing", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # executed is *not* shown by default | 
					
						
							|  |  |  |             form = view.make_form(model_class=model.Upgrade, model_instance=upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("executed", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             view.configure_form(form) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("executed", form) | 
					
						
							|  |  |  |             self.assertNotIn("stdout_file", form) | 
					
						
							|  |  |  |             self.assertNotIn("stderr_file", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # but it *is* shown if upgrade is executed | 
					
						
							|  |  |  |             upgrade.executed = datetime.datetime.now() | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |             upgrade.status = enum.UpgradeStatus.SUCCESS | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             form = view.make_form(model_class=model.Upgrade, model_instance=upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("executed", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             view.configure_form(form) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertIn("executed", form) | 
					
						
							|  |  |  |             self.assertIn("stdout_file", form) | 
					
						
							|  |  |  |             self.assertIn("stderr_file", form) | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_objectify(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # user and status are auto-set when creating | 
					
						
							|  |  |  |         self.request.user = user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.method = "POST" | 
					
						
							|  |  |  |         self.request.POST = {"description": "new one"} | 
					
						
							|  |  |  |         with patch.object(view, "creating", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-24 11:29:52 -05:00
										 |  |  |             form = view.make_model_form() | 
					
						
							|  |  |  |             self.assertTrue(form.validate()) | 
					
						
							|  |  |  |             upgrade = view.objectify(form) | 
					
						
							|  |  |  |             self.assertEqual(upgrade.description, "new one") | 
					
						
							|  |  |  |             self.assertIs(upgrade.created_by, user) | 
					
						
							|  |  |  |             self.assertEqual(upgrade.status, enum.UpgradeStatus.PENDING) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_download_path(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 20:43:41 -05:00
										 |  |  |         appdir = self.mkdtemp() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wutta.appdir", appdir) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertEqual(self.app.get_appdir(), appdir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							|  |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							| 
									
										
										
										
											2024-12-03 21:29:05 -06:00
										 |  |  |         uuid = str(upgrade.uuid) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no filename | 
					
						
							|  |  |  |         path = view.download_path(upgrade, None) | 
					
						
							|  |  |  |         self.assertIsNone(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # with filename | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         path = view.download_path(upgrade, "foo.txt") | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             path, | 
					
						
							|  |  |  |             os.path.join(appdir, "data", "upgrades", uuid[:2], uuid[2:], "foo.txt"), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_upgrade_filepath(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 20:43:41 -05:00
										 |  |  |         appdir = self.mkdtemp() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wutta.appdir", appdir) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertEqual(self.app.get_appdir(), appdir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							|  |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							| 
									
										
										
										
											2024-12-03 21:29:05 -06:00
										 |  |  |         uuid = str(upgrade.uuid) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # no filename | 
					
						
							|  |  |  |         path = view.get_upgrade_filepath(upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             path, os.path.join(appdir, "data", "upgrades", uuid[:2], uuid[2:]) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # with filename | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         path = view.get_upgrade_filepath(upgrade, "foo.txt") | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             path, | 
					
						
							|  |  |  |             os.path.join(appdir, "data", "upgrades", uuid[:2], uuid[2:], "foo.txt"), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_delete_instance(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 20:43:41 -05:00
										 |  |  |         appdir = self.mkdtemp() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wutta.appdir", appdir) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertEqual(self.app.get_appdir(), appdir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							|  |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # mock stdout/stderr files | 
					
						
							|  |  |  |         upgrade_dir = view.get_upgrade_filepath(upgrade) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         stdout = view.get_upgrade_filepath(upgrade, "stdout.log") | 
					
						
							|  |  |  |         with open(stdout, "w") as f: | 
					
						
							|  |  |  |             f.write("stdout") | 
					
						
							|  |  |  |         stderr = view.get_upgrade_filepath(upgrade, "stderr.log") | 
					
						
							|  |  |  |         with open(stderr, "w") as f: | 
					
						
							|  |  |  |             f.write("stderr") | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # both upgrade and files are deleted | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(upgrade_dir)) | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(stdout)) | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(stderr)) | 
					
						
							|  |  |  |         self.assertEqual(self.session.query(model.Upgrade).count(), 1) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |             view.delete_instance(upgrade) | 
					
						
							|  |  |  |         self.assertFalse(os.path.exists(upgrade_dir)) | 
					
						
							|  |  |  |         self.assertFalse(os.path.exists(stdout)) | 
					
						
							|  |  |  |         self.assertFalse(os.path.exists(stderr)) | 
					
						
							|  |  |  |         self.assertEqual(self.session.query(model.Upgrade).count(), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_execute_instance(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 20:43:41 -05:00
										 |  |  |         appdir = self.mkdtemp() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wutta.appdir", appdir) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertEqual(self.app.get_appdir(), appdir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							|  |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  |         self.request.user = user | 
					
						
							|  |  |  |         python = sys.executable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # script not yet confiugred | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |         self.assertRaises(ConfigurationError, view.execute_instance, upgrade, user) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # script w/ success | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         goodpy = self.write_file( | 
					
						
							|  |  |  |             "good.py", | 
					
						
							|  |  |  |             """
 | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | import sys | 
					
						
							|  |  |  | sys.stdout.write('hello from good.py') | 
					
						
							|  |  |  | sys.exit(0) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | """,
 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.app.save_setting( | 
					
						
							|  |  |  |             self.session, "wutta.upgrades.command", f"{python} {goodpy}" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertIsNone(upgrade.executed) | 
					
						
							|  |  |  |         self.assertIsNone(upgrade.executed_by) | 
					
						
							|  |  |  |         self.assertEqual(upgrade.status, enum.UpgradeStatus.PENDING) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "Session", return_value=self.session): | 
					
						
							|  |  |  |             with patch.object(self.config, "usedb", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |                 view.execute_instance(upgrade, user) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertIsNotNone(upgrade.executed) | 
					
						
							|  |  |  |         self.assertIs(upgrade.executed_by, user) | 
					
						
							|  |  |  |         self.assertEqual(upgrade.status, enum.UpgradeStatus.SUCCESS) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with open(view.get_upgrade_filepath(upgrade, "stdout.log")) as f: | 
					
						
							|  |  |  |             self.assertEqual(f.read(), "hello from good.py") | 
					
						
							|  |  |  |         with open(view.get_upgrade_filepath(upgrade, "stderr.log")) as f: | 
					
						
							|  |  |  |             self.assertEqual(f.read(), "") | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # need a new record for next test | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # script w/ failure | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         badpy = self.write_file( | 
					
						
							|  |  |  |             "bad.py", | 
					
						
							|  |  |  |             """
 | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | import sys | 
					
						
							|  |  |  | sys.stderr.write('hello from bad.py') | 
					
						
							|  |  |  | sys.exit(42) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | """,
 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.app.save_setting( | 
					
						
							|  |  |  |             self.session, "wutta.upgrades.command", f"{python} {badpy}" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertIsNone(upgrade.executed) | 
					
						
							|  |  |  |         self.assertIsNone(upgrade.executed_by) | 
					
						
							|  |  |  |         self.assertEqual(upgrade.status, enum.UpgradeStatus.PENDING) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "Session", return_value=self.session): | 
					
						
							|  |  |  |             with patch.object(self.config, "usedb", new=True): | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |                 view.execute_instance(upgrade, user) | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |         self.assertIsNotNone(upgrade.executed) | 
					
						
							|  |  |  |         self.assertIs(upgrade.executed_by, user) | 
					
						
							|  |  |  |         self.assertEqual(upgrade.status, enum.UpgradeStatus.FAILURE) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with open(view.get_upgrade_filepath(upgrade, "stdout.log")) as f: | 
					
						
							|  |  |  |             self.assertEqual(f.read(), "") | 
					
						
							|  |  |  |         with open(view.get_upgrade_filepath(upgrade, "stderr.log")) as f: | 
					
						
							|  |  |  |             self.assertEqual(f.read(), "hello from bad.py") | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |     def test_execute_progress(self): | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         enum = self.app.enum | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         upgrade = model.Upgrade( | 
					
						
							|  |  |  |             description="test", created_by=user, status=enum.UpgradeStatus.PENDING | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |         self.session.add(upgrade) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         stdout = self.write_file("stdout.log", "hello 001\n") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.matchdict = {"uuid": upgrade.uuid} | 
					
						
							|  |  |  |         with patch.multiple( | 
					
						
							|  |  |  |             mod.UpgradeView, | 
					
						
							|  |  |  |             Session=MagicMock(return_value=self.session), | 
					
						
							|  |  |  |             get_upgrade_filepath=MagicMock(return_value=stdout), | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # nb. this is used to identify progress tracker | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.session.id = "mockid#1" | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # first call should get the full contents | 
					
						
							|  |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(context.get("complete")) | 
					
						
							|  |  |  |             self.assertFalse(context.get("error")) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             # nb. newline is converted to <br> | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(context["stdout"], "hello 001<br />") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # next call should get any new contents | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             with open(stdout, "a") as f: | 
					
						
							|  |  |  |                 f.write("hello 002\n") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(context.get("complete")) | 
					
						
							|  |  |  |             self.assertFalse(context.get("error")) | 
					
						
							|  |  |  |             self.assertEqual(context["stdout"], "hello 002<br />") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # nb. switch to a different progress tracker | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.session.id = "mockid#2" | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # first call should get the full contents | 
					
						
							|  |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(context.get("complete")) | 
					
						
							|  |  |  |             self.assertFalse(context.get("error")) | 
					
						
							|  |  |  |             self.assertEqual(context["stdout"], "hello 001<br />hello 002<br />") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # mark progress complete | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             session = get_progress_session(self.request, "upgrades.execute") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             session.load() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             session["complete"] = True | 
					
						
							|  |  |  |             session["success_msg"] = "yay!" | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             session.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # next call should reflect that | 
					
						
							|  |  |  |             self.assertEqual(self.request.session.pop_flash(), []) | 
					
						
							|  |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertTrue(context.get("complete")) | 
					
						
							|  |  |  |             self.assertFalse(context.get("error")) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             # nb. this is missing b/c we already got all contents | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("stdout", context) | 
					
						
							|  |  |  |             self.assertEqual(self.request.session.pop_flash(), ["yay!"]) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # nb. switch to a different progress tracker | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.session.id = "mockid#3" | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # first call should get the full contents | 
					
						
							|  |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(context.get("complete")) | 
					
						
							|  |  |  |             self.assertFalse(context.get("error")) | 
					
						
							|  |  |  |             self.assertEqual(context["stdout"], "hello 001<br />hello 002<br />") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # mark progress error | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             session = get_progress_session(self.request, "upgrades.execute") | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             session.load() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             session["error"] = True | 
					
						
							|  |  |  |             session["error_msg"] = "omg!" | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             session.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # next call should reflect that | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(self.request.session.pop_flash("error"), []) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             context = view.execute_progress() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertFalse(context.get("complete")) | 
					
						
							|  |  |  |             self.assertTrue(context.get("error")) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  |             # nb. this is missing b/c we already got all contents | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertNotIn("stdout", context) | 
					
						
							|  |  |  |             self.assertEqual(self.request.session.pop_flash("error"), ["omg!"]) | 
					
						
							| 
									
										
										
										
											2024-08-25 15:52:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-25 12:20:28 -05:00
										 |  |  |     def test_configure_get_simple_settings(self): | 
					
						
							|  |  |  |         # sanity/coverage check | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  |         simple = view.configure_get_simple_settings() |