| 1 | """ |
|---|
| 2 | Ported to Python 3. |
|---|
| 3 | """ |
|---|
| 4 | |
|---|
| 5 | # We're going to override stdin/stderr, so want to match their behavior on respective Python versions. |
|---|
| 6 | from io import StringIO |
|---|
| 7 | |
|---|
| 8 | from twisted.python.usage import ( |
|---|
| 9 | UsageError, |
|---|
| 10 | ) |
|---|
| 11 | from twisted.python.filepath import ( |
|---|
| 12 | FilePath, |
|---|
| 13 | ) |
|---|
| 14 | |
|---|
| 15 | from testtools.matchers import ( |
|---|
| 16 | Contains, |
|---|
| 17 | ) |
|---|
| 18 | |
|---|
| 19 | from allmydata.scripts.admin import ( |
|---|
| 20 | migrate_crawler, |
|---|
| 21 | add_grid_manager_cert, |
|---|
| 22 | ) |
|---|
| 23 | from allmydata.scripts.runner import ( |
|---|
| 24 | Options, |
|---|
| 25 | ) |
|---|
| 26 | from allmydata.util import jsonbytes as json |
|---|
| 27 | from ..common import ( |
|---|
| 28 | SyncTestCase, |
|---|
| 29 | ) |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | class AdminMigrateCrawler(SyncTestCase): |
|---|
| 33 | """ |
|---|
| 34 | Tests related to 'tahoe admin migrate-crawler' |
|---|
| 35 | """ |
|---|
| 36 | |
|---|
| 37 | def test_already(self): |
|---|
| 38 | """ |
|---|
| 39 | We've already migrated; don't do it again. |
|---|
| 40 | """ |
|---|
| 41 | |
|---|
| 42 | root = FilePath(self.mktemp()) |
|---|
| 43 | storage = root.child("storage") |
|---|
| 44 | storage.makedirs() |
|---|
| 45 | with storage.child("lease_checker.state.json").open("w") as f: |
|---|
| 46 | f.write(b"{}\n") |
|---|
| 47 | |
|---|
| 48 | top = Options() |
|---|
| 49 | top.parseOptions([ |
|---|
| 50 | "admin", "migrate-crawler", |
|---|
| 51 | "--basedir", storage.parent().path, |
|---|
| 52 | ]) |
|---|
| 53 | options = top.subOptions |
|---|
| 54 | while hasattr(options, "subOptions"): |
|---|
| 55 | options = options.subOptions |
|---|
| 56 | options.stdout = StringIO() |
|---|
| 57 | migrate_crawler(options) |
|---|
| 58 | |
|---|
| 59 | self.assertThat( |
|---|
| 60 | options.stdout.getvalue(), |
|---|
| 61 | Contains("Already converted:"), |
|---|
| 62 | ) |
|---|
| 63 | |
|---|
| 64 | def test_usage(self): |
|---|
| 65 | """ |
|---|
| 66 | We've already migrated; don't do it again. |
|---|
| 67 | """ |
|---|
| 68 | |
|---|
| 69 | root = FilePath(self.mktemp()) |
|---|
| 70 | storage = root.child("storage") |
|---|
| 71 | storage.makedirs() |
|---|
| 72 | with storage.child("lease_checker.state.json").open("w") as f: |
|---|
| 73 | f.write(b"{}\n") |
|---|
| 74 | |
|---|
| 75 | top = Options() |
|---|
| 76 | top.parseOptions([ |
|---|
| 77 | "admin", "migrate-crawler", |
|---|
| 78 | "--basedir", storage.parent().path, |
|---|
| 79 | ]) |
|---|
| 80 | options = top.subOptions |
|---|
| 81 | while hasattr(options, "subOptions"): |
|---|
| 82 | options = options.subOptions |
|---|
| 83 | self.assertThat( |
|---|
| 84 | str(options), |
|---|
| 85 | Contains("security issues with pickle") |
|---|
| 86 | ) |
|---|
| 87 | |
|---|
| 88 | |
|---|
| 89 | fake_cert = { |
|---|
| 90 | "certificate": "{\"expires\":1601687822,\"public_key\":\"pub-v0-cbq6hcf3pxcz6ouoafrbktmkixkeuywpcpbcomzd3lqbkq4nmfga\",\"version\":1}", |
|---|
| 91 | "signature": "fvjd3uvvupf2v6tnvkwjd473u3m3inyqkwiclhp7balmchkmn3px5pei3qyfjnhymq4cjcwvbpqmcwwnwswdtrfkpnlaxuih2zbdmda" |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | class AddCertificateOptions(SyncTestCase): |
|---|
| 96 | """ |
|---|
| 97 | Tests for 'tahoe admin add-grid-manager-cert' option validation |
|---|
| 98 | """ |
|---|
| 99 | def setUp(self): |
|---|
| 100 | self.tahoe = Options() |
|---|
| 101 | return super(AddCertificateOptions, self).setUp() |
|---|
| 102 | |
|---|
| 103 | def test_parse_no_data(self): |
|---|
| 104 | """ |
|---|
| 105 | When no data is passed to stdin an error is produced |
|---|
| 106 | """ |
|---|
| 107 | self.tahoe.stdin = StringIO("") |
|---|
| 108 | self.tahoe.stderr = StringIO() # suppress message |
|---|
| 109 | |
|---|
| 110 | with self.assertRaises(UsageError) as ctx: |
|---|
| 111 | self.tahoe.parseOptions( |
|---|
| 112 | [ |
|---|
| 113 | "admin", "add-grid-manager-cert", |
|---|
| 114 | "--name", "random-name", |
|---|
| 115 | "--filename", "-", |
|---|
| 116 | ] |
|---|
| 117 | ) |
|---|
| 118 | |
|---|
| 119 | self.assertIn( |
|---|
| 120 | "Reading certificate from stdin failed", |
|---|
| 121 | str(ctx.exception) |
|---|
| 122 | ) |
|---|
| 123 | |
|---|
| 124 | def test_read_cert_file(self): |
|---|
| 125 | """ |
|---|
| 126 | A certificate can be read from a file |
|---|
| 127 | """ |
|---|
| 128 | tmp = self.mktemp() |
|---|
| 129 | with open(tmp, "wb") as f: |
|---|
| 130 | f.write(json.dumps_bytes(fake_cert)) |
|---|
| 131 | |
|---|
| 132 | # certificate should be loaded |
|---|
| 133 | self.tahoe.parseOptions( |
|---|
| 134 | [ |
|---|
| 135 | "admin", "add-grid-manager-cert", |
|---|
| 136 | "--name", "random-name", |
|---|
| 137 | "--filename", tmp, |
|---|
| 138 | ] |
|---|
| 139 | ) |
|---|
| 140 | opts = self.tahoe.subOptions.subOptions |
|---|
| 141 | self.assertEqual( |
|---|
| 142 | fake_cert, |
|---|
| 143 | opts.certificate_data |
|---|
| 144 | ) |
|---|
| 145 | |
|---|
| 146 | def test_bad_certificate(self): |
|---|
| 147 | """ |
|---|
| 148 | Unparseable data produces an error |
|---|
| 149 | """ |
|---|
| 150 | self.tahoe.stdin = StringIO("{}") |
|---|
| 151 | self.tahoe.stderr = StringIO() # suppress message |
|---|
| 152 | |
|---|
| 153 | with self.assertRaises(UsageError) as ctx: |
|---|
| 154 | self.tahoe.parseOptions( |
|---|
| 155 | [ |
|---|
| 156 | "admin", "add-grid-manager-cert", |
|---|
| 157 | "--name", "random-name", |
|---|
| 158 | "--filename", "-", |
|---|
| 159 | ] |
|---|
| 160 | ) |
|---|
| 161 | |
|---|
| 162 | self.assertIn( |
|---|
| 163 | "Grid Manager certificate must contain", |
|---|
| 164 | str(ctx.exception) |
|---|
| 165 | ) |
|---|
| 166 | |
|---|
| 167 | |
|---|
| 168 | class AddCertificateCommand(SyncTestCase): |
|---|
| 169 | """ |
|---|
| 170 | Tests for 'tahoe admin add-grid-manager-cert' operation |
|---|
| 171 | """ |
|---|
| 172 | |
|---|
| 173 | def setUp(self): |
|---|
| 174 | self.tahoe = Options() |
|---|
| 175 | self.node_path = FilePath(self.mktemp()) |
|---|
| 176 | self.node_path.makedirs() |
|---|
| 177 | with self.node_path.child("tahoe.cfg").open("w") as f: |
|---|
| 178 | f.write(b"# minimal test config\n") |
|---|
| 179 | return super(AddCertificateCommand, self).setUp() |
|---|
| 180 | |
|---|
| 181 | def test_add_one(self): |
|---|
| 182 | """ |
|---|
| 183 | Adding a certificate succeeds |
|---|
| 184 | """ |
|---|
| 185 | self.tahoe.stdin = StringIO(json.dumps(fake_cert)) |
|---|
| 186 | self.tahoe.stderr = StringIO() |
|---|
| 187 | self.tahoe.parseOptions( |
|---|
| 188 | [ |
|---|
| 189 | "--node-directory", self.node_path.path, |
|---|
| 190 | "admin", "add-grid-manager-cert", |
|---|
| 191 | "--name", "zero", |
|---|
| 192 | "--filename", "-", |
|---|
| 193 | ] |
|---|
| 194 | ) |
|---|
| 195 | self.tahoe.subOptions.subOptions.stdin = self.tahoe.stdin |
|---|
| 196 | self.tahoe.subOptions.subOptions.stderr = self.tahoe.stderr |
|---|
| 197 | rc = add_grid_manager_cert(self.tahoe.subOptions.subOptions) |
|---|
| 198 | |
|---|
| 199 | self.assertEqual(rc, 0) |
|---|
| 200 | self.assertEqual( |
|---|
| 201 | {"zero.cert", "tahoe.cfg"}, |
|---|
| 202 | set(self.node_path.listdir()) |
|---|
| 203 | ) |
|---|
| 204 | self.assertIn( |
|---|
| 205 | "There are now 1 certificates", |
|---|
| 206 | self.tahoe.stderr.getvalue() |
|---|
| 207 | ) |
|---|
| 208 | |
|---|
| 209 | def test_add_two(self): |
|---|
| 210 | """ |
|---|
| 211 | An error message is produced when adding a certificate with a |
|---|
| 212 | duplicate name. |
|---|
| 213 | """ |
|---|
| 214 | self.tahoe.stdin = StringIO(json.dumps(fake_cert)) |
|---|
| 215 | self.tahoe.stderr = StringIO() |
|---|
| 216 | self.tahoe.parseOptions( |
|---|
| 217 | [ |
|---|
| 218 | "--node-directory", self.node_path.path, |
|---|
| 219 | "admin", "add-grid-manager-cert", |
|---|
| 220 | "--name", "zero", |
|---|
| 221 | "--filename", "-", |
|---|
| 222 | ] |
|---|
| 223 | ) |
|---|
| 224 | self.tahoe.subOptions.subOptions.stdin = self.tahoe.stdin |
|---|
| 225 | self.tahoe.subOptions.subOptions.stderr = self.tahoe.stderr |
|---|
| 226 | rc = add_grid_manager_cert(self.tahoe.subOptions.subOptions) |
|---|
| 227 | self.assertEqual(rc, 0) |
|---|
| 228 | |
|---|
| 229 | self.tahoe.stdin = StringIO(json.dumps(fake_cert)) |
|---|
| 230 | self.tahoe.parseOptions( |
|---|
| 231 | [ |
|---|
| 232 | "--node-directory", self.node_path.path, |
|---|
| 233 | "admin", "add-grid-manager-cert", |
|---|
| 234 | "--name", "zero", |
|---|
| 235 | "--filename", "-", |
|---|
| 236 | ] |
|---|
| 237 | ) |
|---|
| 238 | self.tahoe.subOptions.subOptions.stdin = self.tahoe.stdin |
|---|
| 239 | self.tahoe.subOptions.subOptions.stderr = self.tahoe.stderr |
|---|
| 240 | rc = add_grid_manager_cert(self.tahoe.subOptions.subOptions) |
|---|
| 241 | self.assertEqual(rc, 1) |
|---|
| 242 | self.assertIn( |
|---|
| 243 | "Already have certificate for 'zero'", |
|---|
| 244 | self.tahoe.stderr.getvalue() |
|---|
| 245 | ) |
|---|