def test_save_and_load(self): temp = tempfile.mkdtemp() server_store = ServerStore(base_dir=temp) path = join(temp, "servers.json") self.assertFalse(exists(path)) server_store.set("foo", "http://connect.local", "notReallyAnApiKey", ca_data="/certs/connect") self.assertTrue(exists(path)) with open(path, "r") as f: data = f.read() self.assertIn("foo", data) self.assertIn("http://connect.local", data) self.assertIn("notReallyAnApiKey", data) self.assertIn("/certs/connect", data) server_store2 = ServerStore(base_dir=temp) self.assertEqual(server_store.get_all_servers(), server_store2.get_all_servers())
class TestServerMetadata(TestCase): def setUp(self): self.server_store = ServerStore() self.server_store.set("foo", "http://connect.local", "notReallyAnApiKey", ca_data="/certs/connect") self.server_store.set("bar", "http://connect.remote", "differentApiKey", insecure=True) def test_add(self): self.assertEqual( self.server_store.get_by_name("foo"), dict( name="foo", url="http://connect.local", api_key="notReallyAnApiKey", insecure=False, ca_cert="/certs/connect", ), ) self.assertEqual( self.server_store.get_by_name("bar"), dict( name="bar", url="http://connect.remote", api_key="differentApiKey", insecure=True, ca_cert=None, ), ) def test_remove_by_name(self): self.server_store.remove_by_name("foo") self.assertIsNone(self.server_store.get_by_name("foo")) self.assertIsNone(self.server_store.get_by_url("http://connect.local")) self.assertIsNotNone(self.server_store.get_by_name("bar")) self.assertIsNotNone( self.server_store.get_by_url("http://connect.remote")) def test_remove_by_url(self): self.server_store.remove_by_url("http://connect.local") self.assertIsNone(self.server_store.get_by_name("foo")) self.assertIsNone(self.server_store.get_by_url("http://connect.local")) self.assertIsNotNone(self.server_store.get_by_name("bar")) self.assertIsNotNone( self.server_store.get_by_url("http://connect.remote")) def test_remove_not_found(self): self.assertFalse(self.server_store.remove_by_name("frazzle")) self.assertEqual(len(self.server_store.get_all_servers()), 2) self.assertFalse(self.server_store.remove_by_url("http://frazzle")) self.assertEqual(len(self.server_store.get_all_servers()), 2) def test_list(self): servers = self.server_store.get_all_servers() self.assertEqual(len(servers), 2) self.assertEqual(servers[0]["name"], "bar") self.assertEqual(servers[0]["url"], "http://connect.remote") self.assertEqual(servers[1]["name"], "foo") self.assertEqual(servers[1]["url"], "http://connect.local") def check_resolve_call(self, name, server, api_key, insecure, ca_cert, should_be_from_store): server, api_key, insecure, ca_cert, from_store = self.server_store.resolve( name, server, api_key, insecure, ca_cert) self.assertEqual(server, "http://connect.local") self.assertEqual(api_key, "notReallyAnApiKey") self.assertEqual(insecure, False) self.assertEqual(ca_cert, "/certs/connect") self.assertTrue(from_store, should_be_from_store) def test_resolve_by_name(self): self.check_resolve_call("foo", None, None, None, None, True) def test_resolve_by_url(self): self.check_resolve_call(None, "http://connect.local", None, None, None, True) def test_resolve_by_default(self): # with multiple entries, server None will not resolve by default name, server, api_key, insecure, ca_cert = None, None, None, None, None server, api_key, insecure, ca_cert, _ = self.server_store.resolve( name, server, api_key, insecure, ca_cert) self.assertEqual(server, None) # with only a single entry, server None will resolve to that entry self.server_store.remove_by_url("http://connect.remote") self.check_resolve_call(None, None, None, None, None, True) def test_resolve_from_args(self): name, server, api_key, insecure, ca_cert = ( None, "https://secured.connect", "an-api-key", True, "fake-cert", ) server, api_key, insecure, ca_cert, from_store = self.server_store.resolve( name, server, api_key, insecure, ca_cert) self.assertEqual(server, "https://secured.connect") self.assertEqual(api_key, "an-api-key") self.assertTrue(insecure) self.assertEqual(ca_cert, "fake-cert") self.assertFalse(from_store) def test_save_and_load(self): temp = tempfile.mkdtemp() server_store = ServerStore(base_dir=temp) path = join(temp, "servers.json") self.assertFalse(exists(path)) server_store.set("foo", "http://connect.local", "notReallyAnApiKey", ca_data="/certs/connect") self.assertTrue(exists(path)) with open(path, "r") as f: data = f.read() self.assertIn("foo", data) self.assertIn("http://connect.local", data) self.assertIn("notReallyAnApiKey", data) self.assertIn("/certs/connect", data) server_store2 = ServerStore(base_dir=temp) self.assertEqual(server_store.get_all_servers(), server_store2.get_all_servers()) def test_get_path(self): self.assertIn("rsconnect-python", self.server_store.get_path())
class TestBuildMetadata(TestCase): def setUp(self): self.server_store = ServerStore() self.server_store.set("connect", "https://connect.remote:6443", "apiKey", insecure=True) self.server = RSConnectServer("https://connect.remote:6443", "apiKey", True, None) self.build_store = ContentBuildStore(self.server) self.build_store._set("rsconnect_build_running", False) self.build_store._set( "rsconnect_content", { "c96db3f3-87a1-4df5-9f58-eb109c397718": { "guid": "c96db3f3-87a1-4df5-9f58-eb109c397718", "bundle_id": "177", "title": "orphan-proc-shiny-test", "name": "orphan-proc-shiny-test", "app_mode": "shiny", "content_url": "https://connect.remote:6443/content/c96db3f3-87a1-4df5-9f58-eb109c397718/", "dashboard_url": "https://connect.remote:6443/connect/#/apps/c96db3f3-87a1-4df5-9f58-eb109c397718", "created_time": "2021-11-04T18:07:12Z", "last_deployed_time": "2021-11-10T19:10:56Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "rsconnect_build_status": "NEEDS_BUILD", }, "fe673896-f92a-40cc-be4c-e4872bb90a37": { "guid": "fe673896-f92a-40cc-be4c-e4872bb90a37", "bundle_id": "185", "title": "interactive-rmd", "name": "interactive-rmd", "app_mode": "rmd-shiny", "content_url": "https://connect.remote:6443/content/fe673896-f92a-40cc-be4c-e4872bb90a37/", "dashboard_url": "https://connect.remote:6443/connect/#/apps/fe673896-f92a-40cc-be4c-e4872bb90a37", "created_time": "2021-11-15T15:37:53Z", "last_deployed_time": "2021-11-15T15:37:57Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "rsconnect_build_status": "ERROR", }, "a0b6b5a2-5fbe-4293-8310-4f80054bc24f": { "guid": "a0b6b5a2-5fbe-4293-8310-4f80054bc24f", "bundle_id": "184", "title": "stock-report-jupyter", "name": "stock-report-jupyter", "app_mode": "jupyter-static", "content_url": "https://connect.remote:6443/content/a0b6b5a2-5fbe-4293-8310-4f80054bc24f/", "dashboard_url": "https://connect.remote:6443/connect/#/apps/a0b6b5a2-5fbe-4293-8310-4f80054bc24f", "created_time": "2021-11-15T15:27:18Z", "last_deployed_time": "2021-11-15T15:35:27Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "rsconnect_build_status": "RUNNING", }, "23315cc9-ed2a-40ad-9e99-e5e49066531a": { "guid": "23315cc9-ed2a-40ad-9e99-e5e49066531a", "bundle_id": "180", "title": "static-rmd", "name": "static-rmd2", "app_mode": "rmd-static", "content_url": "https://connect.remote:6443/content/23315cc9-ed2a-40ad-9e99-e5e49066531a/", "dashboard_url": "https://connect.remote:6443/connect/#/apps/23315cc9-ed2a-40ad-9e99-e5e49066531a", "created_time": "2021-11-15T15:20:58Z", "last_deployed_time": "2021-11-15T15:25:31Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "rsconnect_build_status": "COMPLETE", "rsconnect_last_build_time": "2021-12-13T18:10:38Z", "rsconnect_last_build_log": "/logs/localhost_3939/23315cc9-ed2a-40ad-9e99-e5e49066531a/ZUf44zVWHjODv1Rq.log", "rsconnect_build_task_result": { "id": "ZUf44zVWHjODv1Rq", "user_id": 1, "result": {"type": "", "data": None}, "finished": True, "code": 0, "error": "", }, }, "015143da-b75f-407c-81b1-99c4a724341e": { "guid": "015143da-b75f-407c-81b1-99c4a724341e", "bundle_id": "176", "title": "plumber-async", "name": "plumber-async", "app_mode": "api", "content_url": "https://connect.remote:6443/content/015143da-b75f-407c-81b1-99c4a724341e/", "dashboard_url": "https://connect.remote:6443/connect/#/apps/015143da-b75f-407c-81b1-99c4a724341e", "created_time": "2021-11-01T20:43:32Z", "last_deployed_time": "2021-11-03T17:48:59Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "rsconnect_build_status": "NEEDS_BUILD", }, }, ) def test_get_build_logs_dir(self): logs_dir = self.build_store.get_build_logs_dir("015143da-b75f-407c-81b1-99c4a724341e") self.assertEqual( join(self.build_store._base_dir, "logs", "connect_remote_6443", "015143da-b75f-407c-81b1-99c4a724341e"), logs_dir, ) def test_get_set_build_running(self): self.assertFalse(self.build_store.get_build_running()) self.build_store.set_build_running(True) self.assertTrue(self.build_store.get_build_running()) def test_add_content_item(self): guid = "015143da-b75f-407c-81b1-99c4a724341e" content = { "bundle_id": "1234", "title": "test item", "app_mode": "api", "dashboard_url": "https://connect.remote:6443/connect/#/apps/%s" % guid, "content_url": "https://connect.remote:6443/content/%s/" % guid, "guid": guid, "name": "test-test-test", "last_deployed_time": "2021-10-25T20:21:37Z", "created_time": "2021-09-01T15:12:17Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", "other_field": "this should be ignored", } self.build_store.add_content_item(content) content = self.build_store.get_content_item(guid) self.assertNotIn("other_field", content) self.assertEqual( content, { "bundle_id": "1234", "title": "test item", "app_mode": "api", "dashboard_url": "https://connect.remote:6443/connect/#/apps/%s" % guid, "content_url": "https://connect.remote:6443/content/%s/" % guid, "guid": guid, "name": "test-test-test", "last_deployed_time": "2021-10-25T20:21:37Z", "created_time": "2021-09-01T15:12:17Z", "owner_guid": "edf26318-0027-4d9d-bbbb-54703ebb1855", }, ) def test_get_content_item(self): self.assertIsNotNone(self.build_store.get_content_item("015143da-b75f-407c-81b1-99c4a724341e")) self.assertIsNone(self.build_store.get_content_item("not real")) self.assertIsNone(self.build_store.get_content_item(None)) def test_remove_content_item(self): guid = "015143da-b75f-407c-81b1-99c4a724341e" self.build_store.remove_content_item(guid, purge=False) items = self.build_store.get_content_items() self.assertEqual(4, len(items)) self.assertNotIn(guid, list(map(lambda x: x["guid"], items))) def test_set_content_item_build_status(self): guid = "015143da-b75f-407c-81b1-99c4a724341e" self.build_store.set_content_item_build_status(guid, BuildStatus.COMPLETE) self.assertEqual(BuildStatus.COMPLETE, self.build_store.get_content_item(guid)["rsconnect_build_status"]) self.build_store.set_content_item_build_status(guid, BuildStatus.ERROR) self.assertEqual(BuildStatus.ERROR, self.build_store.get_content_item(guid)["rsconnect_build_status"]) def test_get_content_items(self): self.assertEqual(5, len(self.build_store.get_content_items())) self.assertEqual(2, len(self.build_store.get_content_items(status=BuildStatus.NEEDS_BUILD))) self.assertEqual(1, len(self.build_store.get_content_items(status=BuildStatus.ERROR)))