@@ -182,10 +182,37 @@ | |||
"special": "iter is unique" | |||
}, | |||
{ | |||
"skip": 1, | |||
"title": "dump is correct", | |||
"cmd": [ "dump" ], | |||
"exit": 0, | |||
"stdout": "ERROR: tag needs to start with a \"+\" (add) or a \"-\" (remove).\n" | |||
"stdout_re": "{.*filename.*newfile.txt.*hashes.*90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c.*size.*19.*type.*file.*}\n{.*foo.*bar=baz.*hashes.*90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c.*type.*metadata.*}\n{.*filename.*test.txt.*90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c.*size.*19.*type.*file.*}\n{.*filename.*newfile.txt.*90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c.*size.*19.*type.*file.*}\n{.*filename.*newfile.txt.*90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c.*size.*19.*type.*file.*}\n" | |||
}, | |||
{ | |||
"title": "that import can be done", | |||
"cmd": [ "import" ], | |||
"stdin": "{\"created_by_ref\": \"e7ad5ea1-1203-4951-9dca-ec852a7b8166\", \"foo\": [\"bar=baz\"], \"hashes\": [\"sha512:90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c\"], \"modified\": \"2022-08-21T00:13:51.245871Z\", \"sig\": \"g7k4plXjzz9y8YwJM2ncCIxaqlBpdbITPvKlDtfO7LSFmbZ-qcj0M0lN9h8twNU-n163dNsDGmQA4_s8pJB0liBHDwkjpYQvxfeztQDWNaVN7Xnh2MOj-wBzUbLTVnsJULXwVQrUjngzWjjGQ3jy6gwA\", \"tag\": [\"\"], \"type\": \"metadata\", \"uuid\": \"25ec10e6-c3d0-4363-a762-899dade7f93c\"}\n{\"created_by_ref\": \"2de7a389-410c-4755-8c62-f3254c7e971e\", \"dir\": \"\", \"filename\": \"FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20220331-d53927b0bae-254105.img.xz\", \"hashes\": [\"sha512:3eba2aa09a79fd7adec32ace93c6725e75b91a55192b5bfa827b893fae1c2cdbc040e282138387797f245c1f27da5e8ff7a02f59ff75c73b3d999d1e0a8752ad\"], \"id\": \"d9e8fc1a-9794-5e70-b67b-11d708ec8947\", \"modified\": \"2022-08-02T07:52:50.216428Z\", \"mtime\": \"2022-03-31T10:15:14.000000Z\", \"sig\": \"F3Ch1BQB57RAgFNKNF5btCRZS3jFmafhvcdoWuu6WHo5JzyhuQ7jNvZkv4tzgWqlMfPecLJMMmSAMcwqorykDWi854ZfKUm3F-JOTk8R7qRKdHd23rwVGDEXtVHv-kynkh8WemPsfc2V1HT8JKG9NhwA\", \"size\": 551750948, \"type\": \"file\", \"uuid\": \"89544934-6ed9-46ca-b8d0-77c5209f798d\"}\n" | |||
}, | |||
{ | |||
"special": "verify store object cnt", | |||
"comment": "and the objects were imported", | |||
"count": 7 | |||
}, | |||
{ | |||
"title": "than an object can be dropped", | |||
"cmd": [ "drop", "25ec10e6-c3d0-4363-a762-899dade7f93c" ] | |||
}, | |||
{ | |||
"special": "verify store object cnt", | |||
"comment": "and the object was dropped", | |||
"count": 6 | |||
}, | |||
{ | |||
"title": "than an object can be dropped", | |||
"cmd": [ "drop", "89544934-6ed9-46ca-b8d0-77c5209f798d" ] | |||
}, | |||
{ | |||
"special": "verify store object cnt", | |||
"comment": "and the object was dropped", | |||
"count": 5 | |||
} | |||
] |
@@ -529,6 +529,20 @@ class ObjectStore(object): | |||
return obj | |||
def drop_uuid(self, uuid): | |||
uuid = _makeuuid(uuid) | |||
obj = self.by_id(uuid) | |||
del self._uuids[uuid] | |||
if obj.type == 'file': | |||
del self._uuids[obj.id] | |||
for j in obj.hashes: | |||
h = self.makehash(j) | |||
self._hashes[h].remove(obj) | |||
def by_id(self, id): | |||
'''Look up an object by it's UUID.''' | |||
@@ -772,7 +786,7 @@ def cmd_dump(options): | |||
persona, objstr = get_objstore(options) | |||
for i in objstr: | |||
print(repr(i)) | |||
print(i.encode('json')) | |||
def cmd_list(options): | |||
persona, objstr = get_objstore(options) | |||
@@ -807,6 +821,33 @@ def cmd_list(options): | |||
write_objstore(options, objstr) | |||
def cmd_import(options): | |||
persona, objstr = get_objstore(options) | |||
jd = json.JSONDecoder() | |||
inp = sys.stdin.read() | |||
while inp: | |||
inp = inp.strip() | |||
jobj, endpos = jd.raw_decode(inp) | |||
obj = MDBase.create_obj(jobj) | |||
objstr.loadobj(obj) | |||
inp = inp[endpos:] | |||
write_objstore(options, objstr) | |||
def cmd_drop(options): | |||
persona, objstr = get_objstore(options) | |||
for i in options.uuids: | |||
objstr.drop_uuid(i) | |||
write_objstore(options, objstr) | |||
def main(): | |||
import argparse | |||
@@ -847,6 +888,14 @@ def main(): | |||
parser_dump = subparsers.add_parser('dump', help='dump all the objects') | |||
parser_dump.set_defaults(func=cmd_dump) | |||
parser_import = subparsers.add_parser('import', help='import objects encoded as json') | |||
parser_import.set_defaults(func=cmd_import) | |||
parser_drop = subparsers.add_parser('drop', help='drop the object specified by UUID') | |||
parser_drop.add_argument('uuids', nargs='+', | |||
help='UUID of object to drop') | |||
parser_drop.set_defaults(func=cmd_drop) | |||
options = parser.parse_args() | |||
fun = options.func | |||
@@ -1349,10 +1398,19 @@ class _TestCases(unittest.TestCase): | |||
with self.subTest(file=f, title=cmd['title']), \ | |||
mock.patch('os.path.expanduser', | |||
side_effect=expandusermock) as eu, \ | |||
mock.patch('sys.stdin', io.StringIO()) as stdin, \ | |||
mock.patch('sys.stdout', io.StringIO()) as stdout, \ | |||
mock.patch('sys.stderr', io.StringIO()) as stderr, \ | |||
mock.patch('sys.argv', [ 'progname', ] + | |||
cmd['cmd']) as argv: | |||
# if there is stdin | |||
test_stdin = cmd.get('stdin', '') | |||
# provide it | |||
stdin.write(test_stdin) | |||
stdin.seek(0) | |||
with self.assertRaises(SystemExit) as cm: | |||
main() | |||