add tenant list metadata to binding tester
This commit is contained in:
parent
d953b961b7
commit
ff216c2f57
|
@ -1,91 +0,0 @@
|
|||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import com.apple.foundationdb.Database;
|
||||
import com.apple.foundationdb.FDB;
|
||||
import com.apple.foundationdb.KeyValue;
|
||||
import com.apple.foundationdb.Tenant;
|
||||
import com.apple.foundationdb.Transaction;
|
||||
import com.apple.foundationdb.tuple.Tuple;
|
||||
import com.apple.foundationdb.KeyArrayResult;
|
||||
import com.apple.foundationdb.TenantManagement;
|
||||
import com.apple.foundationdb.async.AsyncUtil;
|
||||
import static com.apple.foundationdb.async.AsyncUtil.collectRemaining;
|
||||
import com.apple.foundationdb.async.CloseableAsyncIterator;
|
||||
|
||||
public class TenantTest {
|
||||
private FDB fdb;
|
||||
private Database db;
|
||||
CloseableAsyncIterator<KeyValue> tenants;
|
||||
|
||||
public TenantTest() {
|
||||
try {
|
||||
fdb = FDB.selectAPIVersion(710);
|
||||
fdb.options().setTraceEnable(null);
|
||||
db = fdb.open();
|
||||
///*
|
||||
Tuple t1 = Tuple.from("tenant");
|
||||
Tuple t2 = Tuple.from("tenant2");
|
||||
Tuple t3 = Tuple.from("tenant3");
|
||||
//*/
|
||||
/*
|
||||
byte[] t1 = Tuple.from("tenant").pack();
|
||||
byte[] t2 = Tuple.from("tenant2").pack();
|
||||
byte[] t3 = Tuple.from("tenant3").pack();
|
||||
*/
|
||||
System.out.println(t1);
|
||||
System.out.println(t2);
|
||||
System.out.println(t3);
|
||||
|
||||
TenantManagement.createTenant(db, t1).join();
|
||||
TenantManagement.createTenant(db, t2).join();
|
||||
TenantManagement.createTenant(db, t3).join();
|
||||
|
||||
tenants = TenantManagement.listTenants(db, Tuple.from("a").pack(), Tuple.from("z").pack(), 100);
|
||||
|
||||
try {
|
||||
/*
|
||||
List<KeyValue> result = AsyncUtil.collectRemaining(tenants).join();
|
||||
System.out.println("Size: " + result.size());
|
||||
for(int i = 0; i < result.size(); i++) {
|
||||
System.out.println(i);
|
||||
KeyValue res = result.get(i);
|
||||
System.out.println(new String(res.getKey()));
|
||||
System.out.println(new String(res.getValue()));
|
||||
}
|
||||
*/
|
||||
// /*
|
||||
while (tenants.hasNext()) {
|
||||
KeyValue res = tenants.next();
|
||||
System.out.println(new String(res.getKey()));
|
||||
System.out.println(new String(res.getValue()));
|
||||
}
|
||||
// */
|
||||
}
|
||||
finally {
|
||||
tenants.close();
|
||||
}
|
||||
TenantManagement.deleteTenant(db, t1).join();
|
||||
TenantManagement.deleteTenant(db, t2).join();
|
||||
TenantManagement.deleteTenant(db, t3).join();
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new TenantTest().close();
|
||||
}
|
||||
}
|
||||
|
|
@ -38,10 +38,16 @@ The tenant API introduces some new operations:
|
|||
|
||||
Unsets the active tenant.
|
||||
|
||||
#### TENANT_LIST
|
||||
#### TENANT_LIST_NAMES
|
||||
|
||||
Pops the top 3 items off of the stack as BEGIN, END, & LIMIT. Returns list
|
||||
of tenants contained in the range BEGIN to END, numbering LIMIT at most.
|
||||
of tenant names contained in the range BEGIN to END, numbering LIMIT at most.
|
||||
May optionally push a future onto the stack.
|
||||
|
||||
#### TENANT_LIST_METADATA
|
||||
|
||||
Pops the top 3 items off of the stack as BEGIN, END, & LIMIT. Returns list
|
||||
of tenant metadata contained in the range BEGIN to END, numbering LIMIT at most.
|
||||
May optionally push a future onto the stack.
|
||||
|
||||
Updates to Existing Instructions
|
||||
|
|
|
@ -165,7 +165,7 @@ class ApiTest(Test):
|
|||
write_conflicts = ['WRITE_CONFLICT_RANGE', 'WRITE_CONFLICT_KEY', 'DISABLE_WRITE_CONFLICT']
|
||||
txn_sizes = ['GET_APPROXIMATE_SIZE']
|
||||
storage_metrics = ['GET_ESTIMATED_RANGE_SIZE', 'GET_RANGE_SPLIT_POINTS']
|
||||
tenants = ['TENANT_CREATE', 'TENANT_DELETE', 'TENANT_SET_ACTIVE', 'TENANT_CLEAR_ACTIVE', 'TENANT_LIST_NAMES']
|
||||
tenants = ['TENANT_CREATE', 'TENANT_DELETE', 'TENANT_SET_ACTIVE', 'TENANT_CLEAR_ACTIVE', 'TENANT_LIST_NAMES', 'TENANT_LIST_METADATA']
|
||||
|
||||
op_choices += reads
|
||||
op_choices += mutations
|
||||
|
@ -604,6 +604,10 @@ class ApiTest(Test):
|
|||
instructions.push_args(b'', b'\xff', 10000)
|
||||
instructions.append(op)
|
||||
self.add_strings(1)
|
||||
elif op == 'TENANT_LIST_METADATA':
|
||||
instructions.push_args(b'', b'\xff', 10000)
|
||||
instructions.append(op)
|
||||
self.add_strings(1)
|
||||
else:
|
||||
assert False, 'Unknown operation: ' + op
|
||||
|
||||
|
|
|
@ -509,6 +509,37 @@ public class AsyncStackTester {
|
|||
inst.push(output);
|
||||
}, FDB.DEFAULT_EXECUTOR);
|
||||
}
|
||||
else if (op == StackOperation.TENANT_LIST_METADATA) {
|
||||
return inst.popParams(3).thenAcceptAsync(params -> {
|
||||
byte[] begin = (byte[])params.get(0);
|
||||
byte[] end = (byte[])params.get(1);
|
||||
int limit = StackUtils.getInt(params.get(2));
|
||||
CloseableAsyncIterator<KeyValue> tenantIter =
|
||||
TenantManagement.listTenants(inst.context.db, begin, end, limit);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
boolean validData = true;
|
||||
try {
|
||||
while (tenantIter.hasNext()) {
|
||||
KeyValue next = tenantIter.next();
|
||||
String metadata = new String(next.getValue());
|
||||
// Without a JSON parsing library, we try to validate that the metadata consists
|
||||
// of a select few properties using simple string comparison
|
||||
if (metadata.charAt(0) != '{' || metadata.charAt(metadata.length() - 1) != '}' ||
|
||||
!metadata.contains("id") || !metadata.contains("prefix")) {
|
||||
validData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
tenantIter.close();
|
||||
}
|
||||
if (validData) {
|
||||
inst.push("VALID_TENANT_METADATA".getBytes());
|
||||
} else {
|
||||
inst.push("INVALID_TENANT_METADATA".getBytes());
|
||||
}
|
||||
}, FDB.DEFAULT_EXECUTOR);
|
||||
}
|
||||
else if (op == StackOperation.TENANT_SET_ACTIVE) {
|
||||
return inst.popParam().thenAcceptAsync(param -> {
|
||||
byte[] tenantName = (byte[])param;
|
||||
|
@ -519,7 +550,7 @@ public class AsyncStackTester {
|
|||
inst.context.setTenant(Optional.empty());
|
||||
return AsyncUtil.DONE;
|
||||
}
|
||||
else if(op == StackOperation.UNIT_TESTS) {
|
||||
else if (op == StackOperation.UNIT_TESTS) {
|
||||
inst.context.db.options().setLocationCacheSize(100001);
|
||||
return inst.context.db.runAsync(tr -> {
|
||||
FDB fdb = FDB.instance();
|
||||
|
@ -594,7 +625,7 @@ public class AsyncStackTester {
|
|||
throw new RuntimeException("Unit tests failed: " + t.getMessage());
|
||||
});
|
||||
}
|
||||
else if(op == StackOperation.LOG_STACK) {
|
||||
else if (op == StackOperation.LOG_STACK) {
|
||||
return inst.popParam().thenComposeAsync(prefix -> doLogStack(inst, (byte[])prefix), FDB.DEFAULT_EXECUTOR);
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ enum StackOperation {
|
|||
TENANT_CREATE,
|
||||
TENANT_DELETE,
|
||||
TENANT_LIST_NAMES,
|
||||
TENANT_LIST_METADATA,
|
||||
TENANT_SET_ACTIVE,
|
||||
TENANT_CLEAR_ACTIVE,
|
||||
|
||||
|
|
|
@ -453,6 +453,36 @@ public class StackTester {
|
|||
byte[] output = outputStream.toByteArray();
|
||||
inst.push(output);
|
||||
}
|
||||
else if (op == StackOperation.TENANT_LIST_METADATA) {
|
||||
List<Object> params = inst.popParams(3).join();
|
||||
byte[] begin = (byte[])params.get(0);
|
||||
byte[] end = (byte[])params.get(1);
|
||||
int limit = StackUtils.getInt(params.get(2));
|
||||
CloseableAsyncIterator<KeyValue> tenantIter =
|
||||
TenantManagement.listTenants(inst.context.db, begin, end, limit);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
boolean validData = true;
|
||||
try {
|
||||
while (tenantIter.hasNext()) {
|
||||
KeyValue next = tenantIter.next();
|
||||
String metadata = new String(next.getValue());
|
||||
// Without a JSON parsing library, we try to validate that the metadata consists
|
||||
// of a select few properties using simple string comparison
|
||||
if (metadata.charAt(0) != '{' || metadata.charAt(metadata.length() - 1) != '}' ||
|
||||
!metadata.contains("id") || !metadata.contains("prefix")) {
|
||||
validData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
tenantIter.close();
|
||||
}
|
||||
if (validData) {
|
||||
inst.push("VALID_TENANT_METADATA".getBytes());
|
||||
} else {
|
||||
inst.push("INVALID_TENANT_METADATA".getBytes());
|
||||
}
|
||||
}
|
||||
else if (op == StackOperation.TENANT_SET_ACTIVE) {
|
||||
byte[] tenantName = (byte[])inst.popParam().join();
|
||||
inst.context.setTenant(Optional.of(tenantName));
|
||||
|
@ -460,7 +490,7 @@ public class StackTester {
|
|||
else if (op == StackOperation.TENANT_CLEAR_ACTIVE) {
|
||||
inst.context.setTenant(Optional.empty());
|
||||
}
|
||||
else if(op == StackOperation.UNIT_TESTS) {
|
||||
else if (op == StackOperation.UNIT_TESTS) {
|
||||
try {
|
||||
inst.context.db.options().setLocationCacheSize(100001);
|
||||
inst.context.db.run(tr -> {
|
||||
|
@ -538,7 +568,7 @@ public class StackTester {
|
|||
throw new RuntimeException("Unit tests failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
else if(op == StackOperation.LOG_STACK) {
|
||||
else if (op == StackOperation.LOG_STACK) {
|
||||
List<Object> params = inst.popParams(1).join();
|
||||
byte[] prefix = (byte[]) params.get(0);
|
||||
|
||||
|
|
|
@ -131,4 +131,4 @@ def list_tenants(db_or_tr, begin, end, limit):
|
|||
begin = _impl.process_tenant_name(begin)
|
||||
end = _impl.process_tenant_name(end)
|
||||
|
||||
return _list_tenants_impl(db_or_tr, begin, end, limit)
|
||||
return _list_tenants_impl(db_or_tr, begin, end, limit)
|
||||
|
|
|
@ -30,6 +30,7 @@ import time
|
|||
import random
|
||||
import time
|
||||
import traceback
|
||||
import json
|
||||
|
||||
sys.path[:0] = [os.path.join(os.path.dirname(__file__), '..')]
|
||||
import fdb
|
||||
|
@ -612,6 +613,22 @@ class Tester:
|
|||
result += tenant.key
|
||||
result_bytes = bytes(result)
|
||||
inst.push(result_bytes)
|
||||
elif inst.op == six.u("TENANT_LIST_METADATA"):
|
||||
begin, end, limit = inst.pop(3)
|
||||
tenant_list = fdb.tenant_management.list_tenants(self.db, begin, end, limit)
|
||||
valid_data = True
|
||||
for tenant in tenant_list:
|
||||
try:
|
||||
metadata = json.loads(tenant.value)
|
||||
id = metadata["id"]
|
||||
prefix = metadata["prefix"]
|
||||
except (json.decoder.JSONDecodeError, KeyError) as e:
|
||||
valid_data = False
|
||||
break
|
||||
if valid_data:
|
||||
inst.push(b"VALID_TENANT_METADATA")
|
||||
else:
|
||||
inst.push(b"INVALID_TENANT_METADATA")
|
||||
elif inst.op == six.u("UNIT_TESTS"):
|
||||
try:
|
||||
test_db_options(db)
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import fdb
|
||||
import sys
|
||||
|
||||
fdb.api_version(710)
|
||||
db=fdb.open()
|
||||
|
||||
db.options.set_transaction_timeout(2000)
|
||||
|
||||
#tenant = b'tenant'
|
||||
#tenant2 = b'tenant2'
|
||||
#tenant3 = b'tenant3'
|
||||
|
||||
tenant = (u"tenant",)
|
||||
tenant2 = (u"tenant2",)
|
||||
tenant3 = (u"tenant3",)
|
||||
|
||||
fdb.tenant_management.create_tenant(db, tenant)
|
||||
fdb.tenant_management.create_tenant(db, tenant2)
|
||||
fdb.tenant_management.create_tenant(db, tenant3)
|
||||
|
||||
res = fdb.tenant_management.list_tenants(db, (u"a",), (u"z",), 10)
|
||||
#res = fdb.tenant_management.list_tenants(db, b'a', b'z', 10)
|
||||
for t in res:
|
||||
print(t.key.decode())
|
||||
print(t.value.decode())
|
||||
|
||||
fdb.tenant_management.delete_tenant(db, tenant)
|
||||
fdb.tenant_management.delete_tenant(db, tenant2)
|
||||
fdb.tenant_management.delete_tenant(db, tenant3)
|
||||
|
||||
sys.exit(0)
|
Loading…
Reference in New Issue