From 6d098bc5f473ed05819793fbb20709dde41d8a2d Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Wed, 5 Jan 2022 16:42:20 -0500
Subject: [PATCH] Add a test for `get_root_nodes` and fix the implementation

---
 src/_zkapauthorizer/_plugin.py           | 13 +++++----
 src/_zkapauthorizer/tests/test_plugin.py | 36 ++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/src/_zkapauthorizer/_plugin.py b/src/_zkapauthorizer/_plugin.py
index ba94115..4777084 100644
--- a/src/_zkapauthorizer/_plugin.py
+++ b/src/_zkapauthorizer/_plugin.py
@@ -20,12 +20,12 @@ Tahoe-LAFS.
 import random
 from datetime import datetime
 from functools import partial
-from typing import Callable
+from typing import Callable, List
 from weakref import WeakValueDictionary
 
 import attr
 from allmydata.client import _Client
-from allmydata.interfaces import IAnnounceableStorageServer, IFoolscapStoragePlugin
+from allmydata.interfaces import IAnnounceableStorageServer, IFoolscapStoragePlugin, IFilesystemNode
 from allmydata.node import MissingConfigEntry
 from challenge_bypass_ristretto import PublicKey, SigningKey
 from eliot import start_action
@@ -297,13 +297,16 @@ def _create_maintenance_service(reactor, node_config, client_node):
     )
 
 
-def get_root_nodes(client_node, node_config):
+def get_root_nodes(client_node, node_config) -> List[IFilesystemNode]:
+    """
+    Get the configured starting points for lease maintenance traversal.
+    """
     try:
-        rootcap = node_config.get_private_config(b"rootcap")
+        rootcap = node_config.get_private_config("rootcap")
     except MissingConfigEntry:
         return []
     else:
-        return [client_node.create_node_from_uri(rootcap)]
+        return [client_node.create_node_from_uri(rootcap.encode("utf-8"))]
 
 
 def load_signing_key(path):
diff --git a/src/_zkapauthorizer/tests/test_plugin.py b/src/_zkapauthorizer/tests/test_plugin.py
index ce0c16b..3b109f8 100644
--- a/src/_zkapauthorizer/tests/test_plugin.py
+++ b/src/_zkapauthorizer/tests/test_plugin.py
@@ -28,6 +28,7 @@ from allmydata.interfaces import (
     IFoolscapStoragePlugin,
     IStorageServer,
     RIStorageServer,
+    IFilesystemNode,
 )
 from challenge_bypass_ristretto import SigningKey
 from eliot.testing import LoggedMessage, capture_logging
@@ -55,6 +56,7 @@ from testtools.matchers import (
     MatchesAll,
     MatchesListwise,
     MatchesStructure,
+    Not,
 )
 from testtools.twistedsupport import succeeded
 from testtools.twistedsupport._deferred import extract_result
@@ -67,7 +69,7 @@ from twisted.web.resource import IResource
 
 from twisted.plugins.zkapauthorizer import storage_server
 
-from .._plugin import load_signing_key
+from .._plugin import load_signing_key, get_root_nodes
 from .._storage_client import IncorrectStorageServerReference
 from ..controller import DummyRedeemer, IssuerConfigurationMismatch, PaymentController
 from ..foolscap import RIPrivacyPassAuthorizedStorageServer
@@ -351,7 +353,6 @@ class ClientPluginTests(TestCase):
     Tests for the plugin's implementation of
     ``IFoolscapStoragePlugin.get_storage_client``.
     """
-
     @given(tahoe_configs(), announcements())
     def test_interface(self, get_config, announcement):
         """
@@ -640,6 +641,37 @@ class LeaseMaintenanceServiceTests(TestCase):
 
         return create_client_from_config(config)
 
+    @given(tahoe_configs())
+    def test_get_root_nodes_rootcap_present(self, get_config):
+        """
+        ``get_root_nodes`` returns a ``list`` of one ``IFilesystemNode`` provider
+        derived from the contents of the *rootcap* private configuration.
+        """
+        d = self._create(get_config, servers_yaml=None, rootcap=True)
+        client_node = extract_result(d)
+        roots = get_root_nodes(client_node, client_node.config)
+        self.assertThat(
+            roots,
+            MatchesAll(
+                Not(HasLength(0)),
+                AllMatch(Provides([IFilesystemNode])),
+            ),
+        )
+
+    @given(tahoe_configs())
+    def test_get_root_nodes_rootcap_missing(self, get_config):
+        """
+        ``get_root_nodes`` returns an empty ``list`` if there is no private
+        *rootcap* configuration.
+        """
+        d = self._create(get_config, servers_yaml=None, rootcap=False)
+        client_node = extract_result(d)
+        roots = get_root_nodes(client_node, client_node.config)
+        self.assertThat(
+            roots,
+            Equals([]),
+        )
+
     @settings(
         deadline=None,
     )
-- 
GitLab