|
|
@ -2,65 +2,72 @@ |
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. |
|
|
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. |
|
|
|
from __future__ import absolute_import, division, print_function, unicode_literals |
|
|
|
from __future__ import absolute_import, division, print_function, unicode_literals |
|
|
|
|
|
|
|
|
|
|
|
import os |
|
|
|
|
|
|
|
import glob |
|
|
|
import glob |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os |
|
|
|
import os.path |
|
|
|
import os.path |
|
|
|
|
|
|
|
import re |
|
|
|
import shutil |
|
|
|
import shutil |
|
|
|
import subprocess |
|
|
|
import subprocess |
|
|
|
|
|
|
|
import tempfile |
|
|
|
import time |
|
|
|
import time |
|
|
|
import unittest |
|
|
|
import unittest |
|
|
|
import tempfile |
|
|
|
|
|
|
|
import re |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def my_check_output(*popenargs, **kwargs): |
|
|
|
def my_check_output(*popenargs, **kwargs): |
|
|
|
""" |
|
|
|
""" |
|
|
|
If we had python 2.7, we should simply use subprocess.check_output. |
|
|
|
If we had python 2.7, we should simply use subprocess.check_output. |
|
|
|
This is a stop-gap solution for python 2.6 |
|
|
|
This is a stop-gap solution for python 2.6 |
|
|
|
""" |
|
|
|
""" |
|
|
|
if 'stdout' in kwargs: |
|
|
|
if "stdout" in kwargs: |
|
|
|
raise ValueError('stdout argument not allowed, it will be overridden.') |
|
|
|
raise ValueError("stdout argument not allowed, it will be overridden.") |
|
|
|
process = subprocess.Popen(stderr=subprocess.PIPE, stdout=subprocess.PIPE, |
|
|
|
process = subprocess.Popen( |
|
|
|
*popenargs, **kwargs) |
|
|
|
stderr=subprocess.PIPE, stdout=subprocess.PIPE, *popenargs, **kwargs |
|
|
|
|
|
|
|
) |
|
|
|
output, unused_err = process.communicate() |
|
|
|
output, unused_err = process.communicate() |
|
|
|
retcode = process.poll() |
|
|
|
retcode = process.poll() |
|
|
|
if retcode: |
|
|
|
if retcode: |
|
|
|
cmd = kwargs.get("args") |
|
|
|
cmd = kwargs.get("args") |
|
|
|
if cmd is None: |
|
|
|
if cmd is None: |
|
|
|
cmd = popenargs[0] |
|
|
|
cmd = popenargs[0] |
|
|
|
raise Exception("Exit code is not 0. It is %d. Command: %s" % |
|
|
|
raise Exception("Exit code is not 0. It is %d. Command: %s" % (retcode, cmd)) |
|
|
|
(retcode, cmd)) |
|
|
|
return output.decode("utf-8") |
|
|
|
return output.decode('utf-8') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_err_null(cmd): |
|
|
|
def run_err_null(cmd): |
|
|
|
return os.system(cmd + " 2>/dev/null ") |
|
|
|
return os.system(cmd + " 2>/dev/null ") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LDBTestCase(unittest.TestCase): |
|
|
|
class LDBTestCase(unittest.TestCase): |
|
|
|
def setUp(self): |
|
|
|
def setUp(self): |
|
|
|
self.TMP_DIR = tempfile.mkdtemp(prefix="ldb_test_") |
|
|
|
self.TMP_DIR = tempfile.mkdtemp(prefix="ldb_test_") |
|
|
|
self.DB_NAME = "testdb" |
|
|
|
self.DB_NAME = "testdb" |
|
|
|
|
|
|
|
|
|
|
|
def tearDown(self): |
|
|
|
def tearDown(self): |
|
|
|
assert(self.TMP_DIR.strip() != "/" |
|
|
|
assert ( |
|
|
|
and self.TMP_DIR.strip() != "/tmp" |
|
|
|
self.TMP_DIR.strip() != "/" |
|
|
|
and self.TMP_DIR.strip() != "/tmp/") #Just some paranoia |
|
|
|
and self.TMP_DIR.strip() != "/tmp" |
|
|
|
|
|
|
|
and self.TMP_DIR.strip() != "/tmp/" |
|
|
|
|
|
|
|
) # Just some paranoia |
|
|
|
|
|
|
|
|
|
|
|
shutil.rmtree(self.TMP_DIR) |
|
|
|
shutil.rmtree(self.TMP_DIR) |
|
|
|
|
|
|
|
|
|
|
|
def dbParam(self, dbName): |
|
|
|
def dbParam(self, dbName): |
|
|
|
return "--db=%s" % os.path.join(self.TMP_DIR, dbName) |
|
|
|
return "--db=%s" % os.path.join(self.TMP_DIR, dbName) |
|
|
|
|
|
|
|
|
|
|
|
def assertRunOKFull(self, params, expectedOutput, unexpected=False, |
|
|
|
def assertRunOKFull( |
|
|
|
isPattern=False): |
|
|
|
self, params, expectedOutput, unexpected=False, isPattern=False |
|
|
|
|
|
|
|
): |
|
|
|
""" |
|
|
|
""" |
|
|
|
All command-line params must be specified. |
|
|
|
All command-line params must be specified. |
|
|
|
Allows full flexibility in testing; for example: missing db param. |
|
|
|
Allows full flexibility in testing; for example: missing db param. |
|
|
|
""" |
|
|
|
""" |
|
|
|
output = my_check_output("./ldb %s |grep -v \"Created bg thread\"" % |
|
|
|
output = my_check_output( |
|
|
|
params, shell=True) |
|
|
|
'./ldb %s |grep -v "Created bg thread"' % params, shell=True |
|
|
|
|
|
|
|
) |
|
|
|
if not unexpected: |
|
|
|
if not unexpected: |
|
|
|
if isPattern: |
|
|
|
if isPattern: |
|
|
|
self.assertNotEqual(expectedOutput.search(output.strip()), |
|
|
|
self.assertNotEqual(expectedOutput.search(output.strip()), None) |
|
|
|
None) |
|
|
|
|
|
|
|
else: |
|
|
|
else: |
|
|
|
self.assertEqual(output.strip(), expectedOutput.strip()) |
|
|
|
self.assertEqual(output.strip(), expectedOutput.strip()) |
|
|
|
else: |
|
|
|
else: |
|
|
@ -76,20 +83,25 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
""" |
|
|
|
""" |
|
|
|
try: |
|
|
|
try: |
|
|
|
|
|
|
|
|
|
|
|
my_check_output("./ldb %s >/dev/null 2>&1 |grep -v \"Created bg \ |
|
|
|
my_check_output( |
|
|
|
thread\"" % params, shell=True) |
|
|
|
'./ldb %s >/dev/null 2>&1 |grep -v "Created bg \ |
|
|
|
|
|
|
|
thread"' |
|
|
|
|
|
|
|
% params, |
|
|
|
|
|
|
|
shell=True, |
|
|
|
|
|
|
|
) |
|
|
|
except Exception: |
|
|
|
except Exception: |
|
|
|
return |
|
|
|
return |
|
|
|
self.fail( |
|
|
|
self.fail( |
|
|
|
"Exception should have been raised for command with params: %s" % |
|
|
|
"Exception should have been raised for command with params: %s" % params |
|
|
|
params) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def assertRunOK(self, params, expectedOutput, unexpected=False): |
|
|
|
def assertRunOK(self, params, expectedOutput, unexpected=False): |
|
|
|
""" |
|
|
|
""" |
|
|
|
Uses the default test db. |
|
|
|
Uses the default test db. |
|
|
|
""" |
|
|
|
""" |
|
|
|
self.assertRunOKFull("%s %s" % (self.dbParam(self.DB_NAME), params), |
|
|
|
self.assertRunOKFull( |
|
|
|
expectedOutput, unexpected) |
|
|
|
"%s %s" % (self.dbParam(self.DB_NAME), params), expectedOutput, unexpected |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def assertRunFAIL(self, params): |
|
|
|
def assertRunFAIL(self, params): |
|
|
|
""" |
|
|
|
""" |
|
|
@ -118,16 +130,17 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
|
|
|
|
|
|
|
|
self.assertRunOK("scan --to=x2", "x1 : y1") |
|
|
|
self.assertRunOK("scan --to=x2", "x1 : y1") |
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=1", "x1 : y1") |
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=1", "x1 : y1") |
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=2", |
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=2", "x1 : y1\nx2 : y2") |
|
|
|
"x1 : y1\nx2 : y2") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=3", |
|
|
|
self.assertRunOK( |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3") |
|
|
|
"scan --from=x1 --to=z --max_keys=3", "x1 : y1\nx2 : y2\nx3 : y3" |
|
|
|
self.assertRunOK("scan --from=x1 --to=z --max_keys=4", |
|
|
|
) |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
"scan --from=x1 --to=z --max_keys=4", "x1 : y1\nx2 : y2\nx3 : y3" |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan --from=x1 --to=x2", "x1 : y1") |
|
|
|
self.assertRunOK("scan --from=x1 --to=x2", "x1 : y1") |
|
|
|
self.assertRunOK("scan --from=x2 --to=x4", "x2 : y2\nx3 : y3") |
|
|
|
self.assertRunOK("scan --from=x2 --to=x4", "x2 : y2\nx3 : y3") |
|
|
|
self.assertRunFAIL("scan --from=x4 --to=z") # No results => FAIL |
|
|
|
self.assertRunFAIL("scan --from=x4 --to=z") # No results => FAIL |
|
|
|
self.assertRunFAIL("scan --from=x1 --to=z --max_keys=foo") |
|
|
|
self.assertRunFAIL("scan --from=x1 --to=z --max_keys=foo") |
|
|
|
|
|
|
|
|
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3") |
|
|
@ -148,18 +161,18 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
return 0 == run_err_null("cat %s | ./ldb load %s" % (dumpFile, params)) |
|
|
|
return 0 == run_err_null("cat %s | ./ldb load %s" % (dumpFile, params)) |
|
|
|
|
|
|
|
|
|
|
|
def writeExternSst(self, params, inputDumpFile, outputSst): |
|
|
|
def writeExternSst(self, params, inputDumpFile, outputSst): |
|
|
|
return 0 == run_err_null("cat %s | ./ldb write_extern_sst %s %s" |
|
|
|
return 0 == run_err_null( |
|
|
|
% (inputDumpFile, outputSst, params)) |
|
|
|
"cat %s | ./ldb write_extern_sst %s %s" % (inputDumpFile, outputSst, params) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def ingestExternSst(self, params, inputSst): |
|
|
|
def ingestExternSst(self, params, inputSst): |
|
|
|
return 0 == run_err_null("./ldb ingest_extern_sst %s %s" |
|
|
|
return 0 == run_err_null("./ldb ingest_extern_sst %s %s" % (inputSst, params)) |
|
|
|
% (inputSst, params)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def testStringBatchPut(self): |
|
|
|
def testStringBatchPut(self): |
|
|
|
print("Running testStringBatchPut...") |
|
|
|
print("Running testStringBatchPut...") |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("scan", "x1 : y1") |
|
|
|
self.assertRunOK("scan", "x1 : y1") |
|
|
|
self.assertRunOK("batchput x2 y2 x3 y3 \"x4 abc\" \"y4 xyz\"", "OK") |
|
|
|
self.assertRunOK('batchput x2 y2 x3 y3 "x4 abc" "y4 xyz"', "OK") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 abc : y4 xyz") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 abc : y4 xyz") |
|
|
|
self.assertRunFAIL("batchput") |
|
|
|
self.assertRunFAIL("batchput") |
|
|
|
self.assertRunFAIL("batchput k1") |
|
|
|
self.assertRunFAIL("batchput k1") |
|
|
@ -171,7 +184,9 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing --enable_blob_files", "OK") |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing --enable_blob_files", "OK") |
|
|
|
self.assertRunOK("scan", "x1 : y1") |
|
|
|
self.assertRunOK("scan", "x1 : y1") |
|
|
|
self.assertRunOK("batchput --enable_blob_files x2 y2 x3 y3 \"x4 abc\" \"y4 xyz\"", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'batchput --enable_blob_files x2 y2 x3 y3 "x4 abc" "y4 xyz"', "OK" |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 abc : y4 xyz") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 abc : y4 xyz") |
|
|
|
|
|
|
|
|
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
@ -195,13 +210,18 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
print("Running testBlobStartingLevel...") |
|
|
|
print("Running testBlobStartingLevel...") |
|
|
|
|
|
|
|
|
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
self.assertRunOK("put --create_if_missing --enable_blob_files --blob_file_starting_level=10 x1 y1", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
"put --create_if_missing --enable_blob_files --blob_file_starting_level=10 x1 y1", |
|
|
|
|
|
|
|
"OK", |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
|
|
|
|
|
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
|
self.assertTrue(len(blob_files) == 0) |
|
|
|
self.assertTrue(len(blob_files) == 0) |
|
|
|
|
|
|
|
|
|
|
|
self.assertRunOK("put --enable_blob_files --blob_file_starting_level=0 x2 y2", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
"put --enable_blob_files --blob_file_starting_level=0 x2 y2", "OK" |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
self.assertRunOK("get x2", "y2") |
|
|
|
self.assertRunOK("get x2", "y2") |
|
|
|
self.assertRunFAIL("get x3") |
|
|
|
self.assertRunFAIL("get x3") |
|
|
@ -213,19 +233,37 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
print("Running testCountDelimDump...") |
|
|
|
print("Running testCountDelimDump...") |
|
|
|
self.assertRunOK("batchput x.1 x1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("batchput x.1 x1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("batchput y.abc abc y.2 2 z.13c pqr", "OK") |
|
|
|
self.assertRunOK("batchput y.abc abc y.2 2 z.13c pqr", "OK") |
|
|
|
self.assertRunOK("dump --count_delim", "x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK("dump --count_delim=\".\"", "x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8") |
|
|
|
"dump --count_delim", |
|
|
|
|
|
|
|
"x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'dump --count_delim="."', |
|
|
|
|
|
|
|
"x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("batchput x,2 x2 x,abc xabc", "OK") |
|
|
|
self.assertRunOK("batchput x,2 x2 x,abc xabc", "OK") |
|
|
|
self.assertRunOK("dump --count_delim=\",\"", "x => count:2\tsize:14\nx.1 => count:1\tsize:5\ny.2 => count:1\tsize:4\ny.abc => count:1\tsize:8\nz.13c => count:1\tsize:8") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'dump --count_delim=","', |
|
|
|
|
|
|
|
"x => count:2\tsize:14\nx.1 => count:1\tsize:5\ny.2 => count:1\tsize:4\ny.abc => count:1\tsize:8\nz.13c => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testCountDelimIDump(self): |
|
|
|
def testCountDelimIDump(self): |
|
|
|
print("Running testCountDelimIDump...") |
|
|
|
print("Running testCountDelimIDump...") |
|
|
|
self.assertRunOK("batchput x.1 x1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("batchput x.1 x1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("batchput y.abc abc y.2 2 z.13c pqr", "OK") |
|
|
|
self.assertRunOK("batchput y.abc abc y.2 2 z.13c pqr", "OK") |
|
|
|
self.assertRunOK("idump --count_delim", "x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK("idump --count_delim=\".\"", "x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8") |
|
|
|
"idump --count_delim", |
|
|
|
|
|
|
|
"x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'idump --count_delim="."', |
|
|
|
|
|
|
|
"x => count:1\tsize:5\ny => count:2\tsize:12\nz => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("batchput x,2 x2 x,abc xabc", "OK") |
|
|
|
self.assertRunOK("batchput x,2 x2 x,abc xabc", "OK") |
|
|
|
self.assertRunOK("idump --count_delim=\",\"", "x => count:2\tsize:14\nx.1 => count:1\tsize:5\ny.2 => count:1\tsize:4\ny.abc => count:1\tsize:8\nz.13c => count:1\tsize:8") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'idump --count_delim=","', |
|
|
|
|
|
|
|
"x => count:2\tsize:14\nx.1 => count:1\tsize:5\ny.2 => count:1\tsize:4\ny.abc => count:1\tsize:8\nz.13c => count:1\tsize:8", |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testInvalidCmdLines(self): |
|
|
|
def testInvalidCmdLines(self): |
|
|
|
print("Running testInvalidCmdLines...") |
|
|
|
print("Running testInvalidCmdLines...") |
|
|
@ -253,12 +291,13 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunOK("get --key_hex 0x6132", "b2") |
|
|
|
self.assertRunOK("get --key_hex 0x6132", "b2") |
|
|
|
self.assertRunOK("get --key_hex --value_hex 0x6132", "0x6232") |
|
|
|
self.assertRunOK("get --key_hex --value_hex 0x6132", "0x6232") |
|
|
|
self.assertRunOK("get --value_hex a2", "0x6232") |
|
|
|
self.assertRunOK("get --value_hex a2", "0x6232") |
|
|
|
self.assertRunOK("scan --key_hex --value_hex", |
|
|
|
self.assertRunOK( |
|
|
|
"0x6131 : 0x6231\n0x6132 : 0x6232") |
|
|
|
"scan --key_hex --value_hex", "0x6131 : 0x6231\n0x6132 : 0x6232" |
|
|
|
self.assertRunOK("scan --hex --from=0x6131 --to=0x6133", |
|
|
|
) |
|
|
|
"0x6131 : 0x6231\n0x6132 : 0x6232") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK("scan --hex --from=0x6131 --to=0x6132", |
|
|
|
"scan --hex --from=0x6131 --to=0x6133", "0x6131 : 0x6231\n0x6132 : 0x6232" |
|
|
|
"0x6131 : 0x6231") |
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOK("scan --hex --from=0x6131 --to=0x6132", "0x6131 : 0x6231") |
|
|
|
self.assertRunOK("scan --key_hex", "0x6131 : b1\n0x6132 : b2") |
|
|
|
self.assertRunOK("scan --key_hex", "0x6131 : b1\n0x6132 : b2") |
|
|
|
self.assertRunOK("scan --value_hex", "a1 : 0x6231\na2 : 0x6232") |
|
|
|
self.assertRunOK("scan --value_hex", "a1 : 0x6231\na2 : 0x6232") |
|
|
|
self.assertRunOK("batchput --hex 0x6133 0x6233 0x6134 0x6234", "OK") |
|
|
|
self.assertRunOK("batchput --hex 0x6133 0x6233 0x6134 0x6234", "OK") |
|
|
@ -272,8 +311,7 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunOK("put a1 b1 --ttl --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put a1 b1 --ttl --create_if_missing", "OK") |
|
|
|
self.assertRunOK("scan --hex", "0x6131 : 0x6231", True) |
|
|
|
self.assertRunOK("scan --hex", "0x6131 : 0x6231", True) |
|
|
|
self.assertRunOK("dump --ttl ", "a1 ==> b1", True) |
|
|
|
self.assertRunOK("dump --ttl ", "a1 ==> b1", True) |
|
|
|
self.assertRunOK("dump --hex --ttl ", |
|
|
|
self.assertRunOK("dump --hex --ttl ", "0x6131 ==> 0x6231\nKeys in range: 1") |
|
|
|
"0x6131 ==> 0x6231\nKeys in range: 1") |
|
|
|
|
|
|
|
self.assertRunOK("scan --hex --ttl", "0x6131 : 0x6231") |
|
|
|
self.assertRunOK("scan --hex --ttl", "0x6131 : 0x6231") |
|
|
|
self.assertRunOK("get --value_hex a1", "0x6231", True) |
|
|
|
self.assertRunOK("get --value_hex a1", "0x6231", True) |
|
|
|
self.assertRunOK("get --ttl a1", "b1") |
|
|
|
self.assertRunOK("get --ttl a1", "b1") |
|
|
@ -295,8 +333,7 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
|
|
|
|
|
|
|
|
def testDumpLoad(self): |
|
|
|
def testDumpLoad(self): |
|
|
|
print("Running testDumpLoad...") |
|
|
|
print("Running testDumpLoad...") |
|
|
|
self.assertRunOK("batchput --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4", |
|
|
|
self.assertRunOK("batchput --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4", "OK") |
|
|
|
"OK") |
|
|
|
|
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
origDbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
origDbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
|
|
|
|
|
|
|
@ -304,98 +341,125 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump1") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump1") |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.assertTrue( |
|
|
|
"--db=%s --create_if_missing" % loadedDbPath, dumpFilePath)) |
|
|
|
self.loadDb("--db=%s --create_if_missing" % loadedDbPath, dumpFilePath) |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
) |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump and load in hex |
|
|
|
# Dump and load in hex |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump2") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump2") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump2") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump2") |
|
|
|
self.assertTrue(self.dumpDb("--db=%s --hex" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.dumpDb("--db=%s --hex" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.assertTrue( |
|
|
|
"--db=%s --hex --create_if_missing" % loadedDbPath, dumpFilePath)) |
|
|
|
self.loadDb( |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
"--db=%s --hex --create_if_missing" % loadedDbPath, dumpFilePath |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump only a portion of the key range |
|
|
|
# Dump only a portion of the key range |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump3") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump3") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump3") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump3") |
|
|
|
self.assertTrue(self.dumpDb( |
|
|
|
self.assertTrue( |
|
|
|
"--db=%s --from=x1 --to=x3" % origDbPath, dumpFilePath)) |
|
|
|
self.dumpDb("--db=%s --from=x1 --to=x3" % origDbPath, dumpFilePath) |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
) |
|
|
|
"--db=%s --create_if_missing" % loadedDbPath, dumpFilePath)) |
|
|
|
self.assertTrue( |
|
|
|
|
|
|
|
self.loadDb("--db=%s --create_if_missing" % loadedDbPath, dumpFilePath) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2") |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2") |
|
|
|
|
|
|
|
|
|
|
|
# Dump upto max_keys rows |
|
|
|
# Dump upto max_keys rows |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump4") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump4") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump4") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump4") |
|
|
|
self.assertTrue(self.dumpDb( |
|
|
|
self.assertTrue(self.dumpDb("--db=%s --max_keys=3" % origDbPath, dumpFilePath)) |
|
|
|
"--db=%s --max_keys=3" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue( |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.loadDb("--db=%s --create_if_missing" % loadedDbPath, dumpFilePath) |
|
|
|
"--db=%s --create_if_missing" % loadedDbPath, dumpFilePath)) |
|
|
|
) |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3") |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Load into an existing db, create_if_missing is not specified |
|
|
|
# Load into an existing db, create_if_missing is not specified |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.loadDb("--db=%s" % loadedDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.loadDb("--db=%s" % loadedDbPath, dumpFilePath)) |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
self.assertRunOKFull( |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump and load with WAL disabled |
|
|
|
# Dump and load with WAL disabled |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump5") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump5") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump5") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump5") |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.assertTrue( |
|
|
|
"--db=%s --disable_wal --create_if_missing" % loadedDbPath, |
|
|
|
self.loadDb( |
|
|
|
dumpFilePath)) |
|
|
|
"--db=%s --disable_wal --create_if_missing" % loadedDbPath, dumpFilePath |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
) |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump and load with lots of extra params specified |
|
|
|
# Dump and load with lots of extra params specified |
|
|
|
extraParams = " ".join(["--bloom_bits=14", "--block_size=1024", |
|
|
|
extraParams = " ".join( |
|
|
|
"--auto_compaction=true", |
|
|
|
[ |
|
|
|
"--write_buffer_size=4194304", |
|
|
|
"--bloom_bits=14", |
|
|
|
"--file_size=2097152"]) |
|
|
|
"--block_size=1024", |
|
|
|
|
|
|
|
"--auto_compaction=true", |
|
|
|
|
|
|
|
"--write_buffer_size=4194304", |
|
|
|
|
|
|
|
"--file_size=2097152", |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
) |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump6") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump6") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump6") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump6") |
|
|
|
self.assertTrue(self.dumpDb( |
|
|
|
self.assertTrue( |
|
|
|
"--db=%s %s" % (origDbPath, extraParams), dumpFilePath)) |
|
|
|
self.dumpDb("--db=%s %s" % (origDbPath, extraParams), dumpFilePath) |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
) |
|
|
|
"--db=%s %s --create_if_missing" % (loadedDbPath, extraParams), |
|
|
|
self.assertTrue( |
|
|
|
dumpFilePath)) |
|
|
|
self.loadDb( |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
"--db=%s %s --create_if_missing" % (loadedDbPath, extraParams), |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
dumpFilePath, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump with count_only |
|
|
|
# Dump with count_only |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump7") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump7") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump7") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump7") |
|
|
|
self.assertTrue(self.dumpDb( |
|
|
|
self.assertTrue(self.dumpDb("--db=%s --count_only" % origDbPath, dumpFilePath)) |
|
|
|
"--db=%s --count_only" % origDbPath, dumpFilePath)) |
|
|
|
self.assertTrue( |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.loadDb("--db=%s --create_if_missing" % loadedDbPath, dumpFilePath) |
|
|
|
"--db=%s --create_if_missing" % loadedDbPath, dumpFilePath)) |
|
|
|
) |
|
|
|
# DB should have atleast one value for scan to work |
|
|
|
# DB should have atleast one value for scan to work |
|
|
|
self.assertRunOKFull("put --db=%s k1 v1" % loadedDbPath, "OK") |
|
|
|
self.assertRunOKFull("put --db=%s k1 v1" % loadedDbPath, "OK") |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, "k1 : v1") |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, "k1 : v1") |
|
|
|
|
|
|
|
|
|
|
|
# Dump command fails because of typo in params |
|
|
|
# Dump command fails because of typo in params |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump8") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump8") |
|
|
|
self.assertFalse(self.dumpDb( |
|
|
|
self.assertFalse( |
|
|
|
"--db=%s --create_if_missing" % origDbPath, dumpFilePath)) |
|
|
|
self.dumpDb("--db=%s --create_if_missing" % origDbPath, dumpFilePath) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Dump and load with BlobDB enabled |
|
|
|
# Dump and load with BlobDB enabled |
|
|
|
blobParams = " ".join(["--enable_blob_files", "--min_blob_size=1", |
|
|
|
blobParams = " ".join( |
|
|
|
"--blob_file_size=2097152"]) |
|
|
|
["--enable_blob_files", "--min_blob_size=1", "--blob_file_size=2097152"] |
|
|
|
|
|
|
|
) |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump9") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump9") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump9") |
|
|
|
loadedDbPath = os.path.join(self.TMP_DIR, "loaded_from_dump9") |
|
|
|
self.assertTrue(self.dumpDb( |
|
|
|
self.assertTrue(self.dumpDb("--db=%s" % (origDbPath), dumpFilePath)) |
|
|
|
"--db=%s" % (origDbPath), dumpFilePath)) |
|
|
|
self.assertTrue( |
|
|
|
self.assertTrue(self.loadDb( |
|
|
|
self.loadDb( |
|
|
|
"--db=%s %s --create_if_missing --disable_wal" % (loadedDbPath, blobParams), |
|
|
|
"--db=%s %s --create_if_missing --disable_wal" |
|
|
|
dumpFilePath)) |
|
|
|
% (loadedDbPath, blobParams), |
|
|
|
self.assertRunOKFull("scan --db=%s" % loadedDbPath, |
|
|
|
dumpFilePath, |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % loadedDbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4" |
|
|
|
|
|
|
|
) |
|
|
|
blob_files = self.getBlobFiles(loadedDbPath) |
|
|
|
blob_files = self.getBlobFiles(loadedDbPath) |
|
|
|
self.assertTrue(len(blob_files) >= 1) |
|
|
|
self.assertTrue(len(blob_files) >= 1) |
|
|
|
|
|
|
|
|
|
|
@ -404,12 +468,14 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunOK("put a val --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put a val --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put b val", "OK") |
|
|
|
self.assertRunOK("put b val", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK( |
|
|
|
"idump", "'a' seq:1, type:1 => val\n" |
|
|
|
"idump", |
|
|
|
"'b' seq:2, type:1 => val\nInternal keys in range: 2") |
|
|
|
"'a' seq:1, type:1 => val\n" |
|
|
|
|
|
|
|
"'b' seq:2, type:1 => val\nInternal keys in range: 2", |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK( |
|
|
|
"idump --input_key_hex --from=%s --to=%s" % (hex(ord('a')), |
|
|
|
"idump --input_key_hex --from=%s --to=%s" % (hex(ord("a")), hex(ord("b"))), |
|
|
|
hex(ord('b'))), |
|
|
|
"'a' seq:1, type:1 => val\nInternal keys in range: 1", |
|
|
|
"'a' seq:1, type:1 => val\nInternal keys in range: 1") |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testIDumpDecodeBlobIndex(self): |
|
|
|
def testIDumpDecodeBlobIndex(self): |
|
|
|
print("Running testIDumpDecodeBlobIndex...") |
|
|
|
print("Running testIDumpDecodeBlobIndex...") |
|
|
@ -420,45 +486,55 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
regex = ".*\[blob ref\].*" |
|
|
|
regex = ".*\[blob ref\].*" |
|
|
|
expected_pattern = re.compile(regex) |
|
|
|
expected_pattern = re.compile(regex) |
|
|
|
cmd = "idump %s --decode_blob_index" |
|
|
|
cmd = "idump %s --decode_blob_index" |
|
|
|
self.assertRunOKFull((cmd) |
|
|
|
self.assertRunOKFull( |
|
|
|
% (self.dbParam(self.DB_NAME)), |
|
|
|
(cmd) % (self.dbParam(self.DB_NAME)), |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
expected_pattern, |
|
|
|
isPattern=True) |
|
|
|
unexpected=False, |
|
|
|
|
|
|
|
isPattern=True, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testMiscAdminTask(self): |
|
|
|
def testMiscAdminTask(self): |
|
|
|
print("Running testMiscAdminTask...") |
|
|
|
print("Running testMiscAdminTask...") |
|
|
|
# These tests need to be improved; for example with asserts about |
|
|
|
# These tests need to be improved; for example with asserts about |
|
|
|
# whether compaction or level reduction actually took place. |
|
|
|
# whether compaction or level reduction actually took place. |
|
|
|
self.assertRunOK("batchput --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4", |
|
|
|
self.assertRunOK("batchput --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4", "OK") |
|
|
|
"OK") |
|
|
|
|
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
origDbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
origDbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
|
|
|
|
|
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue(0 == run_err_null("./ldb compact --db=%s" % origDbPath)) |
|
|
|
"./ldb compact --db=%s" % origDbPath)) |
|
|
|
|
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue( |
|
|
|
"./ldb reduce_levels --db=%s --new_levels=2" % origDbPath)) |
|
|
|
0 == run_err_null("./ldb reduce_levels --db=%s --new_levels=2" % origDbPath) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue( |
|
|
|
"./ldb reduce_levels --db=%s --new_levels=3" % origDbPath)) |
|
|
|
0 == run_err_null("./ldb reduce_levels --db=%s --new_levels=3" % origDbPath) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue( |
|
|
|
"./ldb compact --db=%s --from=x1 --to=x3" % origDbPath)) |
|
|
|
0 == run_err_null("./ldb compact --db=%s --from=x1 --to=x3" % origDbPath) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue( |
|
|
|
"./ldb compact --db=%s --hex --from=0x6131 --to=0x6134" |
|
|
|
0 |
|
|
|
% origDbPath)) |
|
|
|
== run_err_null( |
|
|
|
|
|
|
|
"./ldb compact --db=%s --hex --from=0x6131 --to=0x6134" % origDbPath |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
#TODO(dilip): Not sure what should be passed to WAL.Currently corrupted. |
|
|
|
# TODO(dilip): Not sure what should be passed to WAL.Currently corrupted. |
|
|
|
self.assertTrue(0 == run_err_null( |
|
|
|
self.assertTrue( |
|
|
|
"./ldb dump_wal --db=%s --walfile=%s --header" % ( |
|
|
|
0 |
|
|
|
origDbPath, os.path.join(origDbPath, "LOG")))) |
|
|
|
== run_err_null( |
|
|
|
|
|
|
|
"./ldb dump_wal --db=%s --walfile=%s --header" |
|
|
|
|
|
|
|
% (origDbPath, os.path.join(origDbPath, "LOG")) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
self.assertRunOK("scan", "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
|
|
|
|
def testCheckConsistency(self): |
|
|
|
def testCheckConsistency(self): |
|
|
@ -470,8 +546,9 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
self.assertRunOK("get x1", "y1") |
|
|
|
self.assertRunOK("checkconsistency", "OK") |
|
|
|
self.assertRunOK("checkconsistency", "OK") |
|
|
|
|
|
|
|
|
|
|
|
sstFilePath = my_check_output("ls %s" % os.path.join(dbPath, "*.sst"), |
|
|
|
sstFilePath = my_check_output( |
|
|
|
shell=True) |
|
|
|
"ls %s" % os.path.join(dbPath, "*.sst"), shell=True |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Modify the file |
|
|
|
# Modify the file |
|
|
|
my_check_output("echo 'evil' > %s" % sstFilePath, shell=True) |
|
|
|
my_check_output("echo 'evil' > %s" % sstFilePath, shell=True) |
|
|
@ -482,8 +559,7 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunFAIL("checkconsistency") |
|
|
|
self.assertRunFAIL("checkconsistency") |
|
|
|
|
|
|
|
|
|
|
|
def dumpLiveFiles(self, params, dumpFile): |
|
|
|
def dumpLiveFiles(self, params, dumpFile): |
|
|
|
return 0 == run_err_null("./ldb dump_live_files %s > %s" % ( |
|
|
|
return 0 == run_err_null("./ldb dump_live_files %s > %s" % (params, dumpFile)) |
|
|
|
params, dumpFile)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def testDumpLiveFiles(self): |
|
|
|
def testDumpLiveFiles(self): |
|
|
|
print("Running testDumpLiveFiles...") |
|
|
|
print("Running testDumpLiveFiles...") |
|
|
@ -506,7 +582,12 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
dbPath += "/" |
|
|
|
dbPath += "/" |
|
|
|
|
|
|
|
|
|
|
|
# Call the dump_live_files function with the edited dbPath name. |
|
|
|
# Call the dump_live_files function with the edited dbPath name. |
|
|
|
self.assertTrue(self.dumpLiveFiles("--db=%s --decode_blob_index --dump_uncompressed_blobs" % dbPath, dumpFilePath)) |
|
|
|
self.assertTrue( |
|
|
|
|
|
|
|
self.dumpLiveFiles( |
|
|
|
|
|
|
|
"--db=%s --decode_blob_index --dump_uncompressed_blobs" % dbPath, |
|
|
|
|
|
|
|
dumpFilePath, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Investigate the output |
|
|
|
# Investigate the output |
|
|
|
with open(dumpFilePath, "r") as tmp: |
|
|
|
with open(dumpFilePath, "r") as tmp: |
|
|
@ -517,14 +598,14 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertTrue(len(sstFileList) >= 1) |
|
|
|
self.assertTrue(len(sstFileList) >= 1) |
|
|
|
for sstFilename in sstFileList: |
|
|
|
for sstFilename in sstFileList: |
|
|
|
filenumber = re.findall(r"\d+.sst", sstFilename)[0] |
|
|
|
filenumber = re.findall(r"\d+.sst", sstFilename)[0] |
|
|
|
self.assertEqual(sstFilename, dbPath+filenumber) |
|
|
|
self.assertEqual(sstFilename, dbPath + filenumber) |
|
|
|
|
|
|
|
|
|
|
|
# Check that all the Blob filenames have a correct full path (no multiple '/'). |
|
|
|
# Check that all the Blob filenames have a correct full path (no multiple '/'). |
|
|
|
blobFileList = re.findall(r"%s.*\d+.blob" % dbPath, data) |
|
|
|
blobFileList = re.findall(r"%s.*\d+.blob" % dbPath, data) |
|
|
|
self.assertTrue(len(blobFileList) >= 1) |
|
|
|
self.assertTrue(len(blobFileList) >= 1) |
|
|
|
for blobFilename in blobFileList: |
|
|
|
for blobFilename in blobFileList: |
|
|
|
filenumber = re.findall(r"\d+.blob", blobFilename)[0] |
|
|
|
filenumber = re.findall(r"\d+.blob", blobFilename)[0] |
|
|
|
self.assertEqual(blobFilename, dbPath+filenumber) |
|
|
|
self.assertEqual(blobFilename, dbPath + filenumber) |
|
|
|
|
|
|
|
|
|
|
|
# Check that all the manifest filenames |
|
|
|
# Check that all the manifest filenames |
|
|
|
# have a correct full path (no multiple '/'). |
|
|
|
# have a correct full path (no multiple '/'). |
|
|
@ -532,15 +613,16 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertTrue(len(manifestFileList) >= 1) |
|
|
|
self.assertTrue(len(manifestFileList) >= 1) |
|
|
|
for manifestFilename in manifestFileList: |
|
|
|
for manifestFilename in manifestFileList: |
|
|
|
filenumber = re.findall(r"(?<=MANIFEST-)\d+", manifestFilename)[0] |
|
|
|
filenumber = re.findall(r"(?<=MANIFEST-)\d+", manifestFilename)[0] |
|
|
|
self.assertEqual(manifestFilename, dbPath+"MANIFEST-"+filenumber) |
|
|
|
self.assertEqual(manifestFilename, dbPath + "MANIFEST-" + filenumber) |
|
|
|
|
|
|
|
|
|
|
|
# Check that the blob file index is decoded. |
|
|
|
# Check that the blob file index is decoded. |
|
|
|
decodedBlobIndex = re.findall(r"\[blob ref\]", data) |
|
|
|
decodedBlobIndex = re.findall(r"\[blob ref\]", data) |
|
|
|
self.assertTrue(len(decodedBlobIndex) >= 1) |
|
|
|
self.assertTrue(len(decodedBlobIndex) >= 1) |
|
|
|
|
|
|
|
|
|
|
|
def listLiveFilesMetadata(self, params, dumpFile): |
|
|
|
def listLiveFilesMetadata(self, params, dumpFile): |
|
|
|
return 0 == run_err_null("./ldb list_live_files_metadata %s > %s" % ( |
|
|
|
return 0 == run_err_null( |
|
|
|
params, dumpFile)) |
|
|
|
"./ldb list_live_files_metadata %s > %s" % (params, dumpFile) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testListLiveFilesMetadata(self): |
|
|
|
def testListLiveFilesMetadata(self): |
|
|
|
print("Running testListLiveFilesMetadata...") |
|
|
|
print("Running testListLiveFilesMetadata...") |
|
|
@ -554,23 +636,27 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
dumpFilePath1 = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
dumpFilePath1 = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
self.assertTrue(self.dumpLiveFiles("--db=%s" % dbPath, dumpFilePath1)) |
|
|
|
self.assertTrue(self.dumpLiveFiles("--db=%s" % dbPath, dumpFilePath1)) |
|
|
|
dumpFilePath2 = os.path.join(self.TMP_DIR, "dump2") |
|
|
|
dumpFilePath2 = os.path.join(self.TMP_DIR, "dump2") |
|
|
|
self.assertTrue(self.listLiveFilesMetadata("--sort_by_filename --db=%s" % dbPath, dumpFilePath2)) |
|
|
|
self.assertTrue( |
|
|
|
|
|
|
|
self.listLiveFilesMetadata( |
|
|
|
|
|
|
|
"--sort_by_filename --db=%s" % dbPath, dumpFilePath2 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Collect SST filename and level from dump_live_files |
|
|
|
# Collect SST filename and level from dump_live_files |
|
|
|
with open(dumpFilePath1, "r") as tmp: |
|
|
|
with open(dumpFilePath1, "r") as tmp: |
|
|
|
data = tmp.read() |
|
|
|
data = tmp.read() |
|
|
|
filename1 = re.findall(r".*\d+\.sst",data)[0] |
|
|
|
filename1 = re.findall(r".*\d+\.sst", data)[0] |
|
|
|
level1 = re.findall(r"level:\d+",data)[0].split(':')[1] |
|
|
|
level1 = re.findall(r"level:\d+", data)[0].split(":")[1] |
|
|
|
|
|
|
|
|
|
|
|
# Collect SST filename and level from list_live_files_metadata |
|
|
|
# Collect SST filename and level from list_live_files_metadata |
|
|
|
with open(dumpFilePath2, "r") as tmp: |
|
|
|
with open(dumpFilePath2, "r") as tmp: |
|
|
|
data = tmp.read() |
|
|
|
data = tmp.read() |
|
|
|
filename2 = re.findall(r".*\d+\.sst",data)[0] |
|
|
|
filename2 = re.findall(r".*\d+\.sst", data)[0] |
|
|
|
level2 = re.findall(r"level \d+",data)[0].split(' ')[1] |
|
|
|
level2 = re.findall(r"level \d+", data)[0].split(" ")[1] |
|
|
|
|
|
|
|
|
|
|
|
# Assert equality between filenames and levels. |
|
|
|
# Assert equality between filenames and levels. |
|
|
|
self.assertEqual(filename1,filename2) |
|
|
|
self.assertEqual(filename1, filename2) |
|
|
|
self.assertEqual(level1,level2) |
|
|
|
self.assertEqual(level1, level2) |
|
|
|
|
|
|
|
|
|
|
|
# Create multiple column families and compare the output |
|
|
|
# Create multiple column families and compare the output |
|
|
|
# of list_live_files_metadata with dump_live_files once again. |
|
|
|
# of list_live_files_metadata with dump_live_files once again. |
|
|
@ -586,7 +672,11 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
dumpFilePath3 = os.path.join(self.TMP_DIR, "dump3") |
|
|
|
dumpFilePath3 = os.path.join(self.TMP_DIR, "dump3") |
|
|
|
self.assertTrue(self.dumpLiveFiles("--db=%s" % dbPath, dumpFilePath3)) |
|
|
|
self.assertTrue(self.dumpLiveFiles("--db=%s" % dbPath, dumpFilePath3)) |
|
|
|
dumpFilePath4 = os.path.join(self.TMP_DIR, "dump4") |
|
|
|
dumpFilePath4 = os.path.join(self.TMP_DIR, "dump4") |
|
|
|
self.assertTrue(self.listLiveFilesMetadata("--sort_by_filename --db=%s" % dbPath, dumpFilePath4)) |
|
|
|
self.assertTrue( |
|
|
|
|
|
|
|
self.listLiveFilesMetadata( |
|
|
|
|
|
|
|
"--sort_by_filename --db=%s" % dbPath, dumpFilePath4 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# dump_live_files: |
|
|
|
# dump_live_files: |
|
|
|
# parse the output and create a map: |
|
|
|
# parse the output and create a map: |
|
|
@ -601,7 +691,7 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
# re.findall should not reorder the data. |
|
|
|
# re.findall should not reorder the data. |
|
|
|
# Therefore namesAndLevels[i] matches the data from cfs[i]. |
|
|
|
# Therefore namesAndLevels[i] matches the data from cfs[i]. |
|
|
|
for count, nameAndLevel in enumerate(namesAndLevels): |
|
|
|
for count, nameAndLevel in enumerate(namesAndLevels): |
|
|
|
sstFilename = re.findall(r"\d+.sst",nameAndLevel)[0] |
|
|
|
sstFilename = re.findall(r"\d+.sst", nameAndLevel)[0] |
|
|
|
sstLevel = re.findall(r"(?<=level:)\d+", nameAndLevel)[0] |
|
|
|
sstLevel = re.findall(r"(?<=level:)\d+", nameAndLevel)[0] |
|
|
|
cf = cfs[count] |
|
|
|
cf = cfs[count] |
|
|
|
referenceMap[sstFilename] = [sstLevel, cf] |
|
|
|
referenceMap[sstFilename] = [sstLevel, cf] |
|
|
@ -618,13 +708,13 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
sstLines = re.findall(r".*\d+.sst.*", data) |
|
|
|
sstLines = re.findall(r".*\d+.sst.*", data) |
|
|
|
for line in sstLines: |
|
|
|
for line in sstLines: |
|
|
|
sstFilename = re.findall(r"\d+.sst", line)[0] |
|
|
|
sstFilename = re.findall(r"\d+.sst", line)[0] |
|
|
|
sstLevel = re.findall(r"(?<=level )\d+",line)[0] |
|
|
|
sstLevel = re.findall(r"(?<=level )\d+", line)[0] |
|
|
|
cf = re.findall(r"(?<=column family \')\w+(?=\')",line)[0] |
|
|
|
cf = re.findall(r"(?<=column family \')\w+(?=\')", line)[0] |
|
|
|
testMap[sstFilename] = [sstLevel, cf] |
|
|
|
testMap[sstFilename] = [sstLevel, cf] |
|
|
|
|
|
|
|
|
|
|
|
# Compare the map obtained from dump_live_files and the map |
|
|
|
# Compare the map obtained from dump_live_files and the map |
|
|
|
# obtained from list_live_files_metadata. Everything should match. |
|
|
|
# obtained from list_live_files_metadata. Everything should match. |
|
|
|
self.assertEqual(referenceMap,testMap) |
|
|
|
self.assertEqual(referenceMap, testMap) |
|
|
|
|
|
|
|
|
|
|
|
def getManifests(self, directory): |
|
|
|
def getManifests(self, directory): |
|
|
|
return glob.glob(directory + "/MANIFEST-*") |
|
|
|
return glob.glob(directory + "/MANIFEST-*") |
|
|
@ -657,25 +747,30 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
manifest_files = self.getManifests(dbPath) |
|
|
|
manifest_files = self.getManifests(dbPath) |
|
|
|
self.assertTrue(len(manifest_files) == 1) |
|
|
|
self.assertTrue(len(manifest_files) == 1) |
|
|
|
# Test with the default manifest file in dbPath. |
|
|
|
# Test with the default manifest file in dbPath. |
|
|
|
self.assertRunOKFull(cmd % dbPath, expected_pattern, |
|
|
|
self.assertRunOKFull( |
|
|
|
unexpected=False, isPattern=True) |
|
|
|
cmd % dbPath, expected_pattern, unexpected=False, isPattern=True |
|
|
|
|
|
|
|
) |
|
|
|
self.copyManifests(manifest_files[0], manifest_files[0] + "1") |
|
|
|
self.copyManifests(manifest_files[0], manifest_files[0] + "1") |
|
|
|
manifest_files = self.getManifests(dbPath) |
|
|
|
manifest_files = self.getManifests(dbPath) |
|
|
|
self.assertTrue(len(manifest_files) == 2) |
|
|
|
self.assertTrue(len(manifest_files) == 2) |
|
|
|
# Test with multiple manifest files in dbPath. |
|
|
|
# Test with multiple manifest files in dbPath. |
|
|
|
self.assertRunFAILFull(cmd % dbPath) |
|
|
|
self.assertRunFAILFull(cmd % dbPath) |
|
|
|
# Running it with the copy we just created should pass. |
|
|
|
# Running it with the copy we just created should pass. |
|
|
|
self.assertRunOKFull((cmd + " --path=%s") |
|
|
|
self.assertRunOKFull( |
|
|
|
% (dbPath, manifest_files[1]), |
|
|
|
(cmd + " --path=%s") % (dbPath, manifest_files[1]), |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
expected_pattern, |
|
|
|
isPattern=True) |
|
|
|
unexpected=False, |
|
|
|
|
|
|
|
isPattern=True, |
|
|
|
|
|
|
|
) |
|
|
|
# Make sure that using the dump with --path will result in identical |
|
|
|
# Make sure that using the dump with --path will result in identical |
|
|
|
# output as just using manifest_dump. |
|
|
|
# output as just using manifest_dump. |
|
|
|
cmd = "dump --path=%s" |
|
|
|
cmd = "dump --path=%s" |
|
|
|
self.assertRunOKFull((cmd) |
|
|
|
self.assertRunOKFull( |
|
|
|
% (manifest_files[1]), |
|
|
|
(cmd) % (manifest_files[1]), |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
expected_pattern, |
|
|
|
isPattern=True) |
|
|
|
unexpected=False, |
|
|
|
|
|
|
|
isPattern=True, |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Check if null characters doesn't infer with output format. |
|
|
|
# Check if null characters doesn't infer with output format. |
|
|
|
self.assertRunOK("put a1 b1", "OK") |
|
|
|
self.assertRunOK("put a1 b1", "OK") |
|
|
@ -696,11 +791,14 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
# Also note that 0x72=r and 0x4f=O, hence the regex \'r.{2}O\' |
|
|
|
# Also note that 0x72=r and 0x4f=O, hence the regex \'r.{2}O\' |
|
|
|
# (we cannot use null character in the subprocess input either, |
|
|
|
# (we cannot use null character in the subprocess input either, |
|
|
|
# so we have to use '.{2}') |
|
|
|
# so we have to use '.{2}') |
|
|
|
cmd_verbose = "manifest_dump --verbose --db=%s | grep -aq $'\'r.{2}O\'' && echo 'matched' || echo 'not matched'" %dbPath |
|
|
|
cmd_verbose = ( |
|
|
|
|
|
|
|
"manifest_dump --verbose --db=%s | grep -aq $''r.{2}O'' && echo 'matched' || echo 'not matched'" |
|
|
|
self.assertRunOKFull(cmd_verbose , expected_verbose_output, |
|
|
|
% dbPath |
|
|
|
unexpected=False, isPattern=True) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
cmd_verbose, expected_verbose_output, unexpected=False, isPattern=True |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def testGetProperty(self): |
|
|
|
def testGetProperty(self): |
|
|
|
print("Running testGetProperty...") |
|
|
|
print("Running testGetProperty...") |
|
|
@ -709,16 +807,15 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
self.assertRunOK("put 2 2", "OK") |
|
|
|
self.assertRunOK("put 2 2", "OK") |
|
|
|
# A "string" property |
|
|
|
# A "string" property |
|
|
|
cmd = "--db=%s get_property rocksdb.estimate-num-keys" |
|
|
|
cmd = "--db=%s get_property rocksdb.estimate-num-keys" |
|
|
|
self.assertRunOKFull(cmd % dbPath, |
|
|
|
self.assertRunOKFull(cmd % dbPath, "rocksdb.estimate-num-keys: 2") |
|
|
|
"rocksdb.estimate-num-keys: 2") |
|
|
|
|
|
|
|
# A "map" property |
|
|
|
# A "map" property |
|
|
|
# FIXME: why doesn't this pick up two entries? |
|
|
|
# FIXME: why doesn't this pick up two entries? |
|
|
|
cmd = "--db=%s get_property rocksdb.aggregated-table-properties" |
|
|
|
cmd = "--db=%s get_property rocksdb.aggregated-table-properties" |
|
|
|
part = "rocksdb.aggregated-table-properties.num_entries: " |
|
|
|
part = "rocksdb.aggregated-table-properties.num_entries: " |
|
|
|
expected_pattern = re.compile(part) |
|
|
|
expected_pattern = re.compile(part) |
|
|
|
self.assertRunOKFull(cmd % dbPath, |
|
|
|
self.assertRunOKFull( |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
cmd % dbPath, expected_pattern, unexpected=False, isPattern=True |
|
|
|
isPattern=True) |
|
|
|
) |
|
|
|
# An invalid property |
|
|
|
# An invalid property |
|
|
|
cmd = "--db=%s get_property rocksdb.this-property-does-not-exist" |
|
|
|
cmd = "--db=%s get_property rocksdb.this-property-does-not-exist" |
|
|
|
self.assertRunFAILFull(cmd % dbPath) |
|
|
|
self.assertRunFAILFull(cmd % dbPath) |
|
|
@ -738,27 +835,27 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
sst_files = self.getSSTFiles(dbPath) |
|
|
|
sst_files = self.getSSTFiles(dbPath) |
|
|
|
self.assertTrue(len(sst_files) >= 1) |
|
|
|
self.assertTrue(len(sst_files) >= 1) |
|
|
|
cmd = "dump --path=%s --decode_blob_index" |
|
|
|
cmd = "dump --path=%s --decode_blob_index" |
|
|
|
self.assertRunOKFull((cmd) |
|
|
|
self.assertRunOKFull( |
|
|
|
% (sst_files[0]), |
|
|
|
(cmd) % (sst_files[0]), expected_pattern, unexpected=False, isPattern=True |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
) |
|
|
|
isPattern=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def testBlobDump(self): |
|
|
|
def testBlobDump(self): |
|
|
|
print("Running testBlobDump") |
|
|
|
print("Running testBlobDump") |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing --enable_blob_files", "OK") |
|
|
|
self.assertRunOK("batchput x1 y1 --create_if_missing --enable_blob_files", "OK") |
|
|
|
self.assertRunOK("batchput --enable_blob_files x2 y2 x3 y3 \"x4 abc\" \"y4 xyz\"", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
|
|
|
|
'batchput --enable_blob_files x2 y2 x3 y3 "x4 abc" "y4 xyz"', "OK" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
# Pattern to expect from blob file dump. |
|
|
|
# Pattern to expect from blob file dump. |
|
|
|
regex = ".*Blob log header[\s\S]*Blob log footer[\s\S]*Read record[\s\S]*Summary" |
|
|
|
regex = ".*Blob log header[\s\S]*Blob log footer[\s\S]*Read record[\s\S]*Summary" # noqa |
|
|
|
expected_pattern = re.compile(regex) |
|
|
|
expected_pattern = re.compile(regex) |
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
|
blob_files = self.getBlobFiles(dbPath) |
|
|
|
self.assertTrue(len(blob_files) >= 1) |
|
|
|
self.assertTrue(len(blob_files) >= 1) |
|
|
|
cmd = "dump --path=%s --dump_uncompressed_blobs" |
|
|
|
cmd = "dump --path=%s --dump_uncompressed_blobs" |
|
|
|
self.assertRunOKFull((cmd) |
|
|
|
self.assertRunOKFull( |
|
|
|
% (blob_files[0]), |
|
|
|
(cmd) % (blob_files[0]), expected_pattern, unexpected=False, isPattern=True |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
) |
|
|
|
isPattern=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def testWALDump(self): |
|
|
|
def testWALDump(self): |
|
|
|
print("Running testWALDump...") |
|
|
|
print("Running testWALDump...") |
|
|
@ -775,15 +872,14 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
wal_files = self.getWALFiles(dbPath) |
|
|
|
wal_files = self.getWALFiles(dbPath) |
|
|
|
self.assertTrue(len(wal_files) >= 1) |
|
|
|
self.assertTrue(len(wal_files) >= 1) |
|
|
|
cmd = "dump --path=%s" |
|
|
|
cmd = "dump --path=%s" |
|
|
|
self.assertRunOKFull((cmd) |
|
|
|
self.assertRunOKFull( |
|
|
|
% (wal_files[0]), |
|
|
|
(cmd) % (wal_files[0]), expected_pattern, unexpected=False, isPattern=True |
|
|
|
expected_pattern, unexpected=False, |
|
|
|
) |
|
|
|
isPattern=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def testListColumnFamilies(self): |
|
|
|
def testListColumnFamilies(self): |
|
|
|
print("Running testListColumnFamilies...") |
|
|
|
print("Running testListColumnFamilies...") |
|
|
|
self.assertRunOK("put x1 y1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put x1 y1 --create_if_missing", "OK") |
|
|
|
cmd = "list_column_families | grep -v \"Column families\"" |
|
|
|
cmd = 'list_column_families | grep -v "Column families"' |
|
|
|
# Test on valid dbPath. |
|
|
|
# Test on valid dbPath. |
|
|
|
self.assertRunOK(cmd, "{default}") |
|
|
|
self.assertRunOK(cmd, "{default}") |
|
|
|
# Test on empty path. |
|
|
|
# Test on empty path. |
|
|
@ -791,34 +887,28 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
|
|
|
|
|
|
|
|
def testColumnFamilies(self): |
|
|
|
def testColumnFamilies(self): |
|
|
|
print("Running testColumnFamilies...") |
|
|
|
print("Running testColumnFamilies...") |
|
|
|
dbPath = os.path.join(self.TMP_DIR, self.DB_NAME) # noqa: F841 T25377293 Grandfathered in |
|
|
|
_ = os.path.join(self.TMP_DIR, self.DB_NAME) |
|
|
|
self.assertRunOK("put cf1_1 1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put cf1_1 1 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put cf1_2 2 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put cf1_2 2 --create_if_missing", "OK") |
|
|
|
self.assertRunOK("put cf1_3 3 --try_load_options", "OK") |
|
|
|
self.assertRunOK("put cf1_3 3 --try_load_options", "OK") |
|
|
|
# Given non-default column family to single CF DB. |
|
|
|
# Given non-default column family to single CF DB. |
|
|
|
self.assertRunFAIL("get cf1_1 --column_family=two") |
|
|
|
self.assertRunFAIL("get cf1_1 --column_family=two") |
|
|
|
self.assertRunOK("create_column_family two", "OK") |
|
|
|
self.assertRunOK("create_column_family two", "OK") |
|
|
|
self.assertRunOK("put cf2_1 1 --create_if_missing --column_family=two", |
|
|
|
self.assertRunOK("put cf2_1 1 --create_if_missing --column_family=two", "OK") |
|
|
|
"OK") |
|
|
|
self.assertRunOK("put cf2_2 2 --create_if_missing --column_family=two", "OK") |
|
|
|
self.assertRunOK("put cf2_2 2 --create_if_missing --column_family=two", |
|
|
|
|
|
|
|
"OK") |
|
|
|
|
|
|
|
self.assertRunOK("delete cf1_2", "OK") |
|
|
|
self.assertRunOK("delete cf1_2", "OK") |
|
|
|
self.assertRunOK("create_column_family three", "OK") |
|
|
|
self.assertRunOK("create_column_family three", "OK") |
|
|
|
self.assertRunOK("delete cf2_2 --column_family=two", "OK") |
|
|
|
self.assertRunOK("delete cf2_2 --column_family=two", "OK") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK("put cf3_1 3 --create_if_missing --column_family=three", "OK") |
|
|
|
"put cf3_1 3 --create_if_missing --column_family=three", |
|
|
|
|
|
|
|
"OK") |
|
|
|
|
|
|
|
self.assertRunOK("get cf1_1 --column_family=default", "1") |
|
|
|
self.assertRunOK("get cf1_1 --column_family=default", "1") |
|
|
|
self.assertRunOK("dump --column_family=two", |
|
|
|
self.assertRunOK("dump --column_family=two", "cf2_1 ==> 1\nKeys in range: 1") |
|
|
|
"cf2_1 ==> 1\nKeys in range: 1") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK("dump --column_family=two --try_load_options", |
|
|
|
"dump --column_family=two --try_load_options", |
|
|
|
"cf2_1 ==> 1\nKeys in range: 1") |
|
|
|
"cf2_1 ==> 1\nKeys in range: 1", |
|
|
|
self.assertRunOK("dump", |
|
|
|
) |
|
|
|
"cf1_1 ==> 1\ncf1_3 ==> 3\nKeys in range: 2") |
|
|
|
self.assertRunOK("dump", "cf1_1 ==> 1\ncf1_3 ==> 3\nKeys in range: 2") |
|
|
|
self.assertRunOK("get cf2_1 --column_family=two", |
|
|
|
self.assertRunOK("get cf2_1 --column_family=two", "1") |
|
|
|
"1") |
|
|
|
self.assertRunOK("get cf3_1 --column_family=three", "3") |
|
|
|
self.assertRunOK("get cf3_1 --column_family=three", |
|
|
|
|
|
|
|
"3") |
|
|
|
|
|
|
|
self.assertRunOK("drop_column_family three", "OK") |
|
|
|
self.assertRunOK("drop_column_family three", "OK") |
|
|
|
# non-existing column family. |
|
|
|
# non-existing column family. |
|
|
|
self.assertRunFAIL("get cf3_1 --column_family=four") |
|
|
|
self.assertRunFAIL("get cf3_1 --column_family=four") |
|
|
@ -830,32 +920,36 @@ class LDBTestCase(unittest.TestCase): |
|
|
|
# Dump, load, write external sst and ingest it in another db |
|
|
|
# Dump, load, write external sst and ingest it in another db |
|
|
|
dbPath = os.path.join(self.TMP_DIR, "db1") |
|
|
|
dbPath = os.path.join(self.TMP_DIR, "db1") |
|
|
|
self.assertRunOK( |
|
|
|
self.assertRunOK( |
|
|
|
"batchput --db=%s --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4" |
|
|
|
"batchput --db=%s --create_if_missing x1 y1 x2 y2 x3 y3 x4 y4" % dbPath, |
|
|
|
% dbPath, |
|
|
|
"OK", |
|
|
|
"OK") |
|
|
|
) |
|
|
|
self.assertRunOK("scan --db=%s" % dbPath, |
|
|
|
self.assertRunOK("scan --db=%s" % dbPath, "x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
"x1 : y1\nx2 : y2\nx3 : y3\nx4 : y4") |
|
|
|
|
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
dumpFilePath = os.path.join(self.TMP_DIR, "dump1") |
|
|
|
with open(dumpFilePath, 'w') as f: |
|
|
|
with open(dumpFilePath, "w") as f: |
|
|
|
f.write("x1 ==> y10\nx2 ==> y20\nx3 ==> y30\nx4 ==> y40") |
|
|
|
f.write("x1 ==> y10\nx2 ==> y20\nx3 ==> y30\nx4 ==> y40") |
|
|
|
externSstPath = os.path.join(self.TMP_DIR, "extern_data1.sst") |
|
|
|
externSstPath = os.path.join(self.TMP_DIR, "extern_data1.sst") |
|
|
|
self.assertTrue(self.writeExternSst("--create_if_missing --db=%s" |
|
|
|
self.assertTrue( |
|
|
|
% dbPath, |
|
|
|
self.writeExternSst( |
|
|
|
dumpFilePath, |
|
|
|
"--create_if_missing --db=%s" % dbPath, dumpFilePath, externSstPath |
|
|
|
externSstPath)) |
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
# cannot ingest if allow_global_seqno is false |
|
|
|
# cannot ingest if allow_global_seqno is false |
|
|
|
self.assertFalse( |
|
|
|
self.assertFalse( |
|
|
|
self.ingestExternSst( |
|
|
|
self.ingestExternSst( |
|
|
|
"--create_if_missing --allow_global_seqno=false --db=%s" |
|
|
|
"--create_if_missing --allow_global_seqno=false --db=%s" % dbPath, |
|
|
|
% dbPath, |
|
|
|
externSstPath, |
|
|
|
externSstPath)) |
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
self.assertTrue( |
|
|
|
self.assertTrue( |
|
|
|
self.ingestExternSst( |
|
|
|
self.ingestExternSst( |
|
|
|
"--create_if_missing --allow_global_seqno --db=%s" |
|
|
|
"--create_if_missing --allow_global_seqno --db=%s" % dbPath, |
|
|
|
% dbPath, |
|
|
|
externSstPath, |
|
|
|
externSstPath)) |
|
|
|
) |
|
|
|
self.assertRunOKFull("scan --db=%s" % dbPath, |
|
|
|
) |
|
|
|
"x1 : y10\nx2 : y20\nx3 : y30\nx4 : y40") |
|
|
|
self.assertRunOKFull( |
|
|
|
|
|
|
|
"scan --db=%s" % dbPath, "x1 : y10\nx2 : y20\nx3 : y30\nx4 : y40" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
if __name__ == "__main__": |
|
|
|
unittest.main() |
|
|
|
unittest.main() |
|
|
|