def scenario(wallets, **kw): global wallet_keys, error, foo_output, bar_output, baz_output, config_paths, put_benchmark_data, get_benchmark_data, aws_key, aws_secret print "patch '%s'" % os.environ.get("BLOCKSTACK_CLIENT_CONFIG") with open(os.environ.get('BLOCKSTACK_CLIENT_CONFIG'), "a+") as f: f.write(s3_config) f.flush() testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_preorder("bar.test", wallets[5].privkey, wallets[6].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_register("bar.test", wallets[5].privkey, wallets[6].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys['foo.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[8].privkey) wallet_keys['bar.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey, payment_privkey=wallets[9].privkey) # migrate profiles for name in ['foo.test', 'bar.test']: res = testlib.migrate_profile(name, proxy=test_proxy, wallet_keys=wallet_keys[name]) if 'error' in res: res['test'] = 'Failed to initialize %s profile' % name print json.dumps(res, indent=4, sort_keys=True) error = True return testlib.next_block(**kw) # set up config file config_path = os.environ['BLOCKSTACK_FILE_CONFIG'] with open(config_path, "w") as f: f.write(TEST_CONFIG_FILE) config_paths = {} # set up config file and upload file for each principal for name in ['foo.test', 'bar.test']: config_dir = os.path.dirname(config_path) + "." + name os.makedirs(config_dir) name_config_path = os.path.join(config_dir, os.path.basename(config_path)) config_paths[name] = name_config_path # config path with open(config_paths[name], "w") as f: f.write(TEST_CONFIG_FILE) # upload paths for sz in file_sizes: upload_path = make_local_upload_path(config_path, name, sz) with open(upload_path, "w") as f: with open("/dev/urandom", "r") as r: # generate file file_data = r.read(sz) f.write(file_data) f.flush() foo_output = os.path.join(os.path.dirname(config_path), 'foo.test-out.txt') foo_fail_output = os.path.join(os.path.dirname(config_path), 'foo.test-out-fail.txt') bar_output = os.path.join(os.path.dirname(config_path), 'bar.test-out.txt') bar_fail_output = os.path.join(os.path.dirname(config_path), 'bar.test-out-fail.txt') # initialize file app res = ysi_file.file_key_regenerate("foo.test", "localhost", config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "localhost", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # send a file from foo.test to bar.test # do so many times for sz in file_sizes: put_benchmark_data[sz] = [] for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) local_path = make_local_upload_path(config_path, 'foo.test', sz) begin = time.time() res = ysi_file.file_put('foo.test', 'localhost', ['bar.test'], upload_name, local_path, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) end = time.time() if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return put_benchmark_data[sz].append(end - begin) # get a file from foo.test, as bar.test # do so many times for sz in file_sizes: get_benchmark_data[sz] = [] for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) src_local_path = make_local_upload_path(config_path, 'foo.test', sz) local_path = make_local_upload_path(config_path, 'bar.test', sz) begin = time.time() res = ysi_file.file_get('bar.test', 'localhost', 'foo.test', upload_name, local_path, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) end = time.time() if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return rc = os.system("cmp \"%s\" \"%s\"" % (src_local_path, local_path)) if rc != 0: raise Exception("Not equal: \"%s\" and \"%s\"" % (src_local_path, local_path)) try: os.unlink(output_path) except: pass get_benchmark_data[sz].append(end - begin) # delete for sz in file_sizes: for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) res = ysi_file.file_delete('foo.test', upload_name, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return
def scenario(wallets, **kw): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end. # nodes cannot talk to anyone else. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} atlas_topology[17000] = [16264, 17001] atlas_topology[17007] = [17006] for i in xrange(1, len(atlas_nodes) - 1): atlas_topology[atlas_nodes[i]] = [ atlas_nodes[i - 1], atlas_nodes[i + 1] ] def chain_drop(src_hostport, dest_hostport): if src_hostport is None: return 0.0 src_host, src_port = ysi_client.utils.url_to_host_port(src_hostport) dest_host, dest_port = ysi_client.utils.url_to_host_port(dest_hostport) if (src_port == 16264 and dest_port == 17000) or (src_port == 17000 and dest_port == 16264): # seed end of the chain return 0.0 if abs(src_port - dest_port) <= 1: # chain link return 0.0 # drop otherwise return 1.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des, drop_probability=chain_drop) print "Waiting 25 seconds for the altas peers to catch up" time.sleep(25.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey( wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state(network_des) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block(**kw) - 1, 1): print "Synchronized!" sys.stdout.flush() synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop(network_des) if not synchronized: print "Not synchronized" sys.stdout.flush() return synchronized
def scenario( wallets, **kw ): global synchronized import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) for i in xrange(0, 10): res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer. network_des = atlas_network.atlas_network_build( [17000], {17000: [16264]}, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" )) atlas_network.atlas_network_start( network_des ) time.sleep(5.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] ) empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile ) value_hash = ysi_client.hash_zonefile( empty_zonefile ) res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 10 seconds for atlas network to converge synchronized = False for i in xrange(0, 10): atlas_network.atlas_print_network_state( network_des ) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop( network_des ) return synchronized
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, key_names, error testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) # migrate profiles res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored in this block print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # make an account res = testlib.ysi_cli_put_account("foo.test", "serviceFoo", "serviceFooID", "foo://bar.com", None, extra_data='foofield=foo!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test account' print json.dumps(res, indent=4, sort_keys=True) error = True return res = testlib.ysi_cli_put_account("foo.test", "deletedService", "deletedServiceID", "foo://deleted", None, extra_data='barfield=bar!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test deletedService account' print json.dumps(res, indent=4, sort_keys=True) error = True return # delete an account res = testlib.ysi_cli_delete_account("foo.test", "deletedService", "deletedServiceID", None, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to delete foo.test deletedService' print json.dumps(res, indent=4, sort_keys=True) error = True return testlib.next_block(**kw)
def scenario( wallets, **kw ): global wallet_keys, error, index_file_data, resource_data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) # sign in and make a token datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.ysi_cli_app_signin("foo.test", datastore_pk, 'http://localhost:8888', ['store_read', 'store_write', 'store_admin']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # export to environment ysi_client.set_secret("BLOCKSTACK_API_SESSION", ses) datastore_id_res = testlib.ysi_cli_datastore_get_id( datastore_pk ) datastore_id = datastore_id_res['datastore_id'] # use random data for file file_data = None with open('/dev/urandom', 'r') as f: file_data = f.read(16384) # make datastore res = testlib.ysi_cli_create_datastore( "foo.test", datastore_pk, ['disk'], ses ) if 'error' in res: print "failed to create datastore: {}".format(res['error']) return False # make directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {}'.format(dpath) res = testlib.ysi_cli_datastore_mkdir( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to mkdir {}: {}'.format(dpath, res['error']) return False # make directories again (should fail with EEXIST) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {} (should fail)'.format(dpath) res = testlib.ysi_cli_datastore_mkdir( "foo.test", datastore_pk, dpath, ses ) if 'error' not in res: print 'accidentally succeeded to mkdir {}: {}'.format(dpath, res) return False if not res.has_key('errno'): print 'no errno in error {}'.format(res) return False if res['errno'] != errno.EEXIST: print 'wrong errno in error {}'.format(res) return False # stat directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_DIR_TYPE: print 'not a directory: {}, {}'.format(dpath, res) return False # list directories for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False print res if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # put files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'putfile {}'.format(dpath) data = '{} hello {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile( "foo.test", datastore_pk, dpath, data, ses ) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # stat files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_FILE_TYPE: print 'not a file: {}, {}'.format(dpath, res) return False # list directories again for dpath, expected in [('/', ['dir1', 'dir2', 'file1', 'file2']), ('/dir1', ['dir3', 'file3']), ('/dir1/dir3', ['dir4', 'file4']), ('/dir1/dir3/dir4', ['file5'])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # get files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # put files again! for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'putfile {}'.format(dpath) data = '{} hello 2 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile( "foo.test", datastore_pk, dpath, data, ses ) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # get files again! for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 2 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # remove files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'deletefile {}'.format(dpath) res = testlib.ysi_cli_datastore_deletefile( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to deletefile {}: {}'.format(dpath, res['error']) return False # stat files (should all fail) for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # get files (should all fail) for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to get {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories, 3rd time for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # remove directories for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {}'.format(dpath) res = testlib.ysi_cli_datastore_rmdir( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to rmdir {}: {}'.format(dpath, res['error']) return False # stat directories (should all fail) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories (should all fail) for dpath, expected in [('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to list {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # remove directories again (should fail) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_rmdir( "foo.test", datastore_pk, dpath, ses ) if 'error' not in res: print 'accidentally succeeded to rmdir twice: {}'.format(res) return False if res.get('errno') != errno.ENOENT: print 'wrong errno on rmdir: {}'.format(res) return False # root should be empty print 'listdir {}'.format('/') res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, '/', ses ) if 'error' in res: print 'failed to listdir /: {}'.format(res['error']) return False if len(res['children'].keys()) > 0: print 'root still has children: {}'.format(res['children'].keys()) return False # delete datastore print 'delete datastore' res = testlib.ysi_cli_delete_datastore( "foo.test", datastore_pk, ses ) if 'error' in res: print 'failed to delete foo-app.com datastore' print json.dumps(res) return False # no more data in disk driver names = os.listdir("/tmp/ysi-disk/mutable") if names != ['foo.test']: print 'improper cleanup' return False testlib.next_block( **kw )
def scenario(wallets, **kw): global wallet_keys, error, index_file_data, resource_data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # migrate profiles res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False # sign in and make a token datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.ysi_cli_app_signin( "foo.test", datastore_pk, 'http://localhost:8888', ['store_read', 'store_write', 'store_admin']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # export to environment ysi_client.set_secret("BLOCKSTACK_API_SESSION", res['token']) ses = res['token'] datastore_id_res = testlib.ysi_cli_datastore_get_id(datastore_pk) datastore_id = datastore_id_res['datastore_id'] # use random data for file file_data = None with open('/dev/urandom', 'r') as f: file_data = f.read(16384) # make datastore with two storage drivers res = testlib.ysi_cli_create_datastore('foo.test', datastore_pk, ['disk', 'test'], ses) if 'error' in res: print "failed to create datastore: {}".format(res['error']) return False # simulate a failure in the 'test' driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # make directories (should all fail, since 'test' is offline; however, 'disk' will have worked) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_mkdir('foo.test', datastore_pk, dpath, ses) if 'error' not in res: print 'accidentally succeeded to mkdir {}: {}'.format(dpath, res) return False # stat directories (should all fail locally due to ENOENT, since the parent directory will not have been updated) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories (all the ones we tried to create should fail due to ENOENT) for dpath, expected in [('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to list {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # restore driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # make directories (should succeed) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {}'.format(dpath) res = testlib.ysi_cli_datastore_mkdir('foo.test', datastore_pk, dpath, ses) if 'error' in res: print 'failed to mkdir {}: {}'.format(dpath, res['error']) return False # make directories (should fail with EEXIST) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {}'.format(dpath) res = testlib.ysi_cli_datastore_mkdir('foo.test', datastore_pk, dpath, ses) if 'error' not in res: print 'accidentally succeeded to mkdir {}: {}'.format(dpath, res) return False if not res.has_key('errno'): print 'no errno in error {}'.format(res) return False if res['errno'] != errno.EEXIST: print 'wrong errno in error {}'.format(res) return False # stat directories (should succeed) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_DIR_TYPE: print 'not a directory: {}, {}'.format(dpath, res) return False # list directories (should succeed) for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # put files for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {}'.format(dpath) data = '{} hello {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile('foo.test', datastore_pk, dpath, data, ses) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # simulate a failure in the 'test' driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # stat files (should succeed) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_FILE_TYPE: print 'not a file: {}, {}'.format(dpath, res) return False # list directories again (should succeed) for dpath, expected in [('/', ['dir1', 'dir2', 'file1', 'file2']), ('/dir1', ['dir3', 'file3']), ('/dir1/dir3', ['dir4', 'file4']), ('/dir1/dir3/dir4', ['file5'])]: print 'listdir {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # get files (should succeed and return latest data) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # put files (should succeed with 'disk', but fail overall since we have a failed driver) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {} (expect failure)'.format(dpath) data = '{} hello 2 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile('foo.test', datastore_pk, dpath, data, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to putfile {}: {}'.format( dpath, res['error']) return False # get files (should get the new data, despite the failed service) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 2 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # restore test driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # put files (should succeed now) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {}'.format(dpath) data = '{} hello 2 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile('foo.test', datastore_pk, dpath, data, ses) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # get files again! should see results of last put for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 2 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # simulate a failure in the 'test' driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # remove files (should fail since 'test' driver is disabled) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'deletefile {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_deletefile('foo.test', datastore_pk, dpath, ses) if 'error' not in res: print 'accidentally failed to deletefile {}: {}'.format( dpath, res['error']) return False # get files (should fail, since the idata was removed from 'disk') for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {} (should fail)'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' not in res: print 'accidentally got {}: {}'.format(dpath, res) return False if res['errno'] != errno.EREMOTEIO: print 'wrong errno: {}'.format(res) return False # stat files (should still work) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to stat {}: {}'.format(path, res) return False # restore test driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # stat files (should still work) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to stat {}: {}'.format(path, res) return False # remove files (should work now) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'deletefile {}'.format(dpath) res = testlib.ysi_cli_datastore_deletefile('foo.test', datastore_pk, dpath, ses) if 'error' in res: print 'failed to deletefile {}: {}'.format(dpath, res) return False # put file data (should succeed on both 'disk' and 'test') for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {}'.format(dpath) data = '{} hello 3 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile('foo.test', datastore_pk, dpath, data, ses) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # get files again! should see results of last put for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 3 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # cause 'test' to fail res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # put file data (should fail, but succeed on 'disk') for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {} (expect failure)'.format(dpath) data = '{} hello 4 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile('foo.test', datastore_pk, dpath, data, ses) if 'error' not in res: print 'accidentally succeeded to putfile {}: {}'.format(dpath, res) return False if res['errno'] != errno.EREMOTEIO: print 'wrong errno: {}'.format(res) return False # get files again! should see results of last put for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 4 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # restore 'test' res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # get files again! should see results of last put for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 4 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # remove files (should succeed) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'deletefile {}'.format(dpath) res = testlib.ysi_cli_datastore_deletefile('foo.test', datastore_pk, dpath, ses) if 'error' in res: print 'failed to deletefile {}: {}'.format(dpath, res['error']) return False # stat files (should all fail) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # get files (should all fail) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to get {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir2', []), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # break 'test' res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # stat files (should all fail) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # get files (should all fail) for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_getfile('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to get {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir2', []), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # remove directories (should fail, but '/dir2' and '/dir1/dir3/dir4''s idata should be gone) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_rmdir('foo.test', datastore_pk, dpath, ses) if 'error' not in res: print 'accidentally succeeded to rmdir {}: {}'.format(dpath, res) return False if dpath not in ['/dir1/dir3/dir4', '/dir2']: if res.get('errno') != errno.ENOTEMPTY: print 'wrong errno for deleting {}'.format(res) return False # list directories (should fail for /dir1/dir3/dir4 and /dir2 since its idata got deleted, but it should still work for everyone else) for dpath, expected in [('/dir2', []), ('/dir1/dir3/dir4', [])]: print 'listdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to list {}: {}'.format(dpath, res) return False if res['errno'] != errno.EREMOTEIO: print 'wrong errno: {}'.format(res) return False # these should still work for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4'])]: print 'listdir {} (should still work)'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # restore service res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # remove directories (should succeed) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {}'.format(dpath) res = testlib.ysi_cli_datastore_rmdir('foo.test', datastore_pk, dpath, ses) if 'error' in res: print 'failed to rmdir {}: {}'.format(dpath, res['error']) return False # stat directories (should all fail) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories (should all fail) for dpath, expected in [('/dir2', []), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, dpath, ses) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to list {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # root should be empty print 'listdir {}'.format('/') res = testlib.ysi_cli_datastore_listdir('foo.test', datastore_id, '/', ses) if 'error' in res: print 'failed to listdir /: {}'.format(res['error']) return False if len(res['children'].keys()) > 0: print 'root still has children: {}'.format(res['children'].keys()) return False # simulate a failure in the 'test' driver res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '1') if 'error' in res: print 'failed to setenv: {}'.format(res) return False # delete datastore (should fail) print 'delete datastore (expect failure)' res = testlib.ysi_cli_delete_datastore('foo.test', datastore_pk, ses) if 'error' not in res: print 'accidentally succeeded to delete datastore' print json.dumps(res) return False # restore service res = testlib.ysi_test_setenv( 'BLOCKSTACK_INTEGRATION_TEST_STORAGE_FAILURE', '0') if 'error' in res: print 'failed to setenv: {}'.format(res) return False print 'delete datastore' res = testlib.ysi_cli_delete_datastore('foo.test', datastore_pk, ses) if 'error' in res: print 'failed to delete foo-app.com datastore' print json.dumps(res) return False # no more data in test-disk driver names = os.listdir("/tmp/ysi-integration-test-storage/mutable") if names != ['foo.test']: print 'improper cleanup on test' return False # due to our failed mkdir of /dir1 and /dir2, these # will have leaked. Expect 5 entries (including foo.test): # an idata and inode header for both dirs names = os.listdir("/tmp/ysi-disk/mutable") if len(names) != 5: print 'imporper cleanup on disk' return False if 'foo.test' not in names: print 'missing foo.test' return False testlib.next_block(**kw)
def scenario(wallets, **kw): global wallet_keys, error, foo_output, bar_output, baz_output, config_paths testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_preorder("bar.test", wallets[5].privkey, wallets[6].addr) testlib.ysi_name_preorder("baz.test", wallets[8].privkey, wallets[9].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_register("bar.test", wallets[5].privkey, wallets[6].addr) testlib.ysi_name_register("baz.test", wallets[8].privkey, wallets[9].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys['foo.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, payment_privkey=wallets[10].privkey) wallet_keys['bar.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[6].privkey, payment_privkey=wallets[11].privkey) wallet_keys['baz.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[9].privkey, payment_privkey=wallets[12].privkey) # migrate profiles for name in ['foo.test', 'bar.test', 'baz.test']: res = testlib.migrate_profile(name, proxy=test_proxy, wallet_keys=wallet_keys[name]) if 'error' in res: res['test'] = 'Failed to initialize %s profile' % name print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # set up config file config_path = os.environ['BLOCKSTACK_FILE_CONFIG'] with open(config_path, "w") as f: f.write(TEST_CONFIG_FILE) config_paths = {} # set up config file and directory for each principal for name in ['foo.test', 'bar.test', 'baz.test']: config_dir = os.path.dirname(config_path) + "." + name os.makedirs(config_dir) name_config_path = os.path.join(config_dir, os.path.basename(config_path)) config_paths[name] = name_config_path with open(config_paths[name], "w") as f: f.write(TEST_CONFIG_FILE) foo_output = os.path.join(os.path.dirname(config_path), 'foo.test-out.txt') foo_fail_output = os.path.join(os.path.dirname(config_path), 'foo.test-out-fail.txt') bar_output = os.path.join(os.path.dirname(config_path), 'bar.test-out.txt') bar_fail_output = os.path.join(os.path.dirname(config_path), 'bar.test-out-fail.txt') baz_output = os.path.join(os.path.dirname(config_path), 'baz.test-out.txt') baz_fail_output = os.path.join(os.path.dirname(config_path), 'baz.test-out-fail.txt') # initialize file app res = ysi_file.file_key_regenerate("foo.test", "localhost", config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "localhost", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "mobile-phone", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("baz.test", "laptop", config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # send a file from foo.test to bar.test and baz.test res = ysi_file.file_put('foo.test', 'localhost', ['bar.test', 'baz.test'], 'config-file-from-foo.test', config_path, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # send a file from bar.test's mobile phone to foo.test (but not baz.test) res = ysi_file.file_put('bar.test', 'mobile-phone', ['foo.test'], 'config-file-from-bar.test', config_path, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # send a file from baz.test's laptop to baz.test's laptop (and no one else) res = ysi_file.file_put('baz.test', 'laptop', [], 'config-file-from-baz.test', config_path, config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have foo.test receive bar.test's file log.debug("foo.test receives bar.test's file") res = ysi_file.file_get('foo.test', 'localhost', 'bar.test', 'config-file-from-bar.test', foo_output, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have bar.test receive bar.test's file to localhost log.debug("bar.test receives bar.tests's file") res = ysi_file.file_get('bar.test', 'localhost', 'bar.test', 'config-file-from-bar.test', bar_output, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have baz.test receive foo.test's file log.debug("baz.test recieves foo.test's file") res = ysi_file.file_get('baz.test', 'laptop', 'foo.test', 'config-file-from-foo.test', baz_output, config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have bar.test receive foo.test's file to its mobile-phone key log.debug("bar.test receives foo.test's file") res = ysi_file.file_get('bar.test', 'mobile-phone', 'foo.test', 'config-file-from-foo.test', bar_output, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have baz.test try to receive bar.test's file (should fail) log.debug("baz.test receives bar.test's file (should fail)") res = ysi_file.file_get('baz.test', 'laptop', 'bar.test', 'config-file-from-bar.test', baz_fail_output, config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) print json.dumps(res, indent=4, sort_keys=True) if 'error' not in res or res['error'] != 'Failed to decrypt data': print 'baz decrypting hidden file: succeeded when we should not have, or failed incorrectly: %s' % res error = True return # have foo.test and bar.test try to receive baz.test's file (should fail) for (name, failpath) in [('foo.test', foo_fail_output), ('bar.test', bar_fail_output)]: log.debug("%s receives baz.test's file (should fail)" % name) res = ysi_file.file_get(name, 'localhost', 'baz.test', 'config-file-from-baz.test', failpath, config_path=config_paths[name], wallet_keys=wallet_keys[name]) print json.dumps(res, indent=4, sort_keys=True) if 'error' not in res or res['error'] != 'Failed to decrypt data': print '%s decrypting hidden file: succeeded when we should not have, or fialed incorrectly: %s' % ( name, res) error = True return # regenerate everyone's keys res = ysi_file.file_key_regenerate("foo.test", "localhost", config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "localhost", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "mobile-phone", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("baz.test", "laptop", config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # have foo.test receive bar.test's file, despite regeneration log.debug("foo.test receives bar.test's file, despite regeneration") res = ysi_file.file_get('foo.test', 'localhost', 'bar.test', 'config-file-from-bar.test', foo_output, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return if 'warning' not in res or res['warning'] != 'Used stale key': print json.dumps(res, indent=4, sort_keys=True) print "did not use stale key" error = True return # have bar.test receive bar.test's file to localhost log.debug("bar.test receives bar.tests's file, despite regeneration") res = ysi_file.file_get('bar.test', 'localhost', 'bar.test', 'config-file-from-bar.test', bar_output, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return if 'warning' not in res or res['warning'] != 'Used stale key': print json.dumps(res, indent=4, sort_keys=True) print "did not use stale key" error = True return # have baz.test receive foo.test's file log.debug("baz.test recieves foo.test's file, despite regeneration") res = ysi_file.file_get('baz.test', 'laptop', 'foo.test', 'config-file-from-foo.test', baz_output, config_path=config_paths['baz.test'], wallet_keys=wallet_keys['baz.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return if 'warning' not in res or res['warning'] != 'Used stale key': print json.dumps(res, indent=4, sort_keys=True) print "did not use stale key" error = True return # have bar.test receive foo.test's file to its mobile-phone key log.debug("bar.test receives foo.test's file, despite regeneration") res = ysi_file.file_get('bar.test', 'mobile-phone', 'foo.test', 'config-file-from-foo.test', bar_output, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return if 'warning' not in res or res['warning'] != 'Used stale key': print json.dumps(res, indent=4, sort_keys=True) print "did not use stale key" error = True return # delete the file from foo log.debug("delete foo.test's file") res = ysi_file.file_delete('foo.test', 'config-file-from-foo.test', config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # delete the file from bar log.debug("delete bar.test's file") res = ysi_file.file_delete('bar.test', 'config-file-from-bar.test', config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # verify that no one can read foo's file for (name, host, failpath) in [('foo.test', 'localhost', foo_fail_output), ('bar.test', 'mobile-phone', bar_fail_output), ('baz.test', 'laptop', baz_fail_output)]: log.debug("%s receives foo.test's deleted file (should fail)" % name) res = ysi_file.file_get(name, host, 'foo.test', 'config-file-from-foo.test', failpath, config_path=config_paths[name], wallet_keys=wallet_keys[name]) print json.dumps(res, indent=4, sort_keys=True) if 'error' not in res or res['error'] != 'Failed to get encrypted file': print 'reading deleted file: succeeded when we should not have, or failed incorrectly: %s' % res error = True return
def scenario( wallets, **kw ): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) for i in xrange(0, 10): res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] ) empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile ) value_hash = ysi_client.hash_zonefile( empty_zonefile ) res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} for node_port in atlas_nodes: atlas_topology[node_port] = [16264] def nat_drop(src_hostport, dest_hostport): if dest_hostport is None: return 0.0 host, port = ysi_client.utils.url_to_host_port( dest_hostport ) if port in atlas_nodes: # connections to the above nodes will always fail, since they're NAT'ed return 1.0 else: # connections to the seed node always succeed return 0.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) ) atlas_network.atlas_network_start( network_des, drop_probability=nat_drop ) print "Waiting 60 seconds for the altas peers to catch up" time.sleep(60.0) # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state( network_des ) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop( network_des ) return synchronized
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, key_names, error, gpghome testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_register( "bar.test", wallets[5].privkey, wallets[6].addr ) testlib.next_block( **kw ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[8].privkey ) wallet_keys_2 = ysi_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey, payment_privkey=wallets[9].privkey ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return res = testlib.migrate_profile( "bar.test", proxy=test_proxy, wallet_keys=wallet_keys_2 ) if 'error' in res: res['test'] = 'Failed to initialize bar.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) # add account keys res = ysi_gpg.gpg_profile_create_key( "foo.test", "foo_test_account_key", immutable=False, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw), gpghome=testlib.gpg_key_dir(**kw), use_key_server=False ) if 'error' in res: res['test'] = 'Failed to create foo.test account key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) res = ysi_gpg.gpg_profile_create_key( "bar.test", "bar_test_account_key", immutable=False, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw), gpghome=testlib.gpg_key_dir(**kw), use_key_server=False ) if 'error' in res: res['test'] = 'Failed to create bar.test account key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['bar.test'].append( res ) testlib.next_block( **kw ) # add immutable app keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "foo.test", "secure_messaging", "foo_test_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) ) if 'error' in res: res['test'] = 'Failed to create foo.test immutable app key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) # set new wallet keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "bar.test", "secure_messaging", "bar_test_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) ) if 'error' in res: res['test'] = 'Failed to create bar.test immutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return else: key_names['bar.test'].append( res ) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) # add mutable app keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "foo.test", "less-secure_messaging", "foo_test_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) ) if 'error' in res: res['test'] = 'Failed to create foo.test mutable app key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) testlib.next_block( **kw ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "bar.test", "less-secure_messaging", "bar_test_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) ) if 'error' in res: res['test'] = 'Failed to create bar.test mutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return else: key_names['bar.test'].append( res ) testlib.next_block( **kw ) # add profile keys that we'll delete testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_profile_create_key( "foo.test", "foo_test_deleted_account_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw), gpghome=testlib.gpg_key_dir(**kw), use_key_server=False) foo_profile_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable foo.test account key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) foo_profile_delete_key_id = res['key_id'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_profile_create_key( "bar.test", "bar_test_deleted_account_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw), gpghome=testlib.gpg_key_dir(**kw), use_key_server=False) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) bar_profile_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable bar.test account key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['bar.test'].append( res ) bar_profile_delete_key_id = res['key_id'] # add immutable app keys, which we can delete testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) ) foo_immutable_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable foo.test immutable app key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) foo_immutable_delete_key_id = res['key_id'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) ) bar_immutable_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable bar.test immutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return else: key_names['bar.test'].append( res ) bar_immutable_delete_key_id = res['key_id'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) # add mutable app keys which we can delete testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) ) foo_mutable_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable mutable foo.test app key' print json.dumps(res, indent=4, sort_keys=True) error = True return else: key_names['foo.test'].append( res ) foo_mutable_delete_key_id = res['key_id'] testlib.next_block( **kw ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_create_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) ) bar_mutable_delete_key_id = None if 'error' in res: res['test'] = 'Failed to create deletable mutable bar.test app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return else: key_names['bar.test'].append( res ) bar_mutable_delete_key_id = res['key_id'] testlib.next_block( **kw ) # delete profile keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_profile_delete_key( "foo.test", foo_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to create deletable account foo.test profile key' print json.dumps(res, indent=4, sort_keys=True ) error = True return testlib.next_block( **kw ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_profile_delete_key( "bar.test", bar_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys_2 ) if 'error' in res: res['test'] = 'Failed to create deletable account bar.test profile key' print json.dumps(res, indent=4, sort_keys=True ) error = True return # delete immutable app keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_delete_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw)) if 'error' in res: res['test'] = 'Failed to create deletable foo.test immutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_delete_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key", immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw)) if 'error' in res: res['test'] = 'Failed to create deletable bar.test immutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for it to go through for i in xrange(0, 12): testlib.next_block( **kw ) print "wait for confirmation" time.sleep(10) # delete mutable app keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = ysi_gpg.gpg_app_delete_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw)) if 'error' in res: res['test'] = 'Failed to create deletable foo.test mutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return testlib.next_block( **kw ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = ysi_gpg.gpg_app_delete_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key", proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw)) if 'error' in res: res['test'] = 'Failed to create deletable bar.test mutable app key' print json.dumps(res, indent=4, sort_keys=True ) error = True return testlib.next_block( **kw ) gpghome = testlib.gpg_key_dir(**kw)
def scenario(wallets, **kw): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey( wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # start up an atlas network with 16 peers, 8 of which will be active at once. # every second, have one peer come online, and one peer go offline. # have them all start out knowing about the same seed node. atlas_nodes = [ 17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007, 17008, 17009, 17010, 17011, 17012, 17013, 17014, 17015, 17016 ] atlas_topology = {} for i in xrange(0, 9): atlas_topology[atlas_nodes[i]] = [16264] for i in xrange(9, len(atlas_nodes)): atlas_topology[atlas_nodes[i]] = [17008] atlas_topology[atlas_nodes[-1]].append(16264) # put the seed after the first four all_peers = atlas_nodes[:4] + [16264] + atlas_nodes[4:] time_start = int(time.time()) + 60 def churn_drop(src_hostport, dest_hostport): if src_hostport is None: return 0.0 src_host, src_port = ysi_client.utils.url_to_host_port(src_hostport) dest_host, dest_port = ysi_client.utils.url_to_host_port(dest_hostport) now = int(time.time()) # offset = (now - time_start) % len(all_peers) offset = now % len(all_peers) sample = all_peers + all_peers active_range = sample[offset:offset + 8] print "Active range: %s, request (%s --> %s)" % (active_range, src_port, dest_port) if src_port not in active_range: # dead return 1.0 if dest_port not in active_range: # dead return 1.0 return 0.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des, drop_probability=churn_drop) print "Waiting 120 seconds for the altas peers to catch up" time.sleep(120.0) # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state(network_des) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block(**kw) - 1, 1): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop(network_des) return synchronized
def scenario(wallets, **kw): global datasets, zonefile_hashes, put_result, last_hash testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) # migrate profile res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False put_result = ysi_client.put_immutable("foo.test", "hello_world_1", json.dumps(datasets[0], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False testlib.expect_atlas_zonefile(put_result['zonefile_hash']) zonefile_hashes.append(put_result['immutable_data_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) put_result = ysi_client.put_immutable("foo.test", "hello_world_2", json.dumps(datasets[1], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False testlib.expect_atlas_zonefile(put_result['zonefile_hash']) zonefile_hashes.append(put_result['immutable_data_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) put_result = ysi_client.put_immutable("foo.test", "hello_world_3", json.dumps(datasets[2], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False testlib.expect_atlas_zonefile(put_result['zonefile_hash']) zonefile_hashes.append(put_result['immutable_data_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) # should succeed (name collision) datasets[0]['newdata'] = "asdf" put_result = ysi_client.put_immutable("foo.test", "hello_world_1", json.dumps(datasets[0], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False zonefile_hashes[0] = put_result['immutable_data_hash'] testlib.expect_atlas_zonefile(put_result['zonefile_hash']) del datasets[0]['newdata'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) # delete everything for i in xrange(0, len(datasets)): print "delete %s" % zonefile_hashes[i] put_result = ysi_client.delete_immutable("foo.test", zonefile_hashes[i], wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for conformation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) last_hash = put_result['zonefile_hash']
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, wallet_keychain, error, index_file_data, resource_data, sessions test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys_2 = ysi_client.make_wallet_keys( owner_privkey=wallets[4].privkey, data_privkey=wallets[5].privkey, payment_privkey=wallets[3].privkey ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) wallet_keychain = { 'foo.test': wallet_keys, 'bar.test': wallet_keys_2, } # install wallet_keys testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_preorder( "bar.test", wallets[3].privkey, wallets[4].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_register( "bar.test", wallets[3].privkey, wallets[4].addr ) testlib.next_block( **kw ) setup_storage_dirs(['foo.test', 'bar.test']) # migrate profiles # BUT! make sure we store the profile for foo.test into both foo.test's and bar.test's storage directories! os.environ['TEST_BLOCKSTACK_TEST_DISK_ROOT'] = '/tmp/ysi-integration-test-storage-foo.test' res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) return False shutil.copy("/tmp/ysi-integration-test-storage-foo.test/mutable/foo.test", "/tmp/ysi-integration-test-storage-bar.test/mutable/foo.test") # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # store zonefile res = ysi_client.proxy.put_zonefiles("localhost:16264", [base64.b64encode(res['zonefile_txt'])]) if 'error' in res: print 'failed to store zonefile for foo.test: {}'.format(res) return False # BUT! make sure we store the profile for bar.test into both foo.test's and bar.test's storage directories! os.environ['TEST_BLOCKSTACK_TEST_DISK_ROOT'] = '/tmp/ysi-integration-test-storage-bar.test' res = testlib.migrate_profile( "bar.test", proxy=test_proxy, wallet_keys=wallet_keys_2 ) if 'error' in res: res['test'] = 'Failed to initialize bar.test profile' print json.dumps(res, indent=4, sort_keys=True) return False shutil.copy("/tmp/ysi-integration-test-storage-bar.test/mutable/bar.test", "/tmp/ysi-integration-test-storage-foo.test/mutable/bar.test") # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # store zonefile res = ysi_client.proxy.put_zonefiles("localhost:16264", [base64.b64encode(res['zonefile_txt'])]) if 'error' in res: print 'failed to store zonefile for bar.test: {}'.format(res) return False res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API for foo.test: {}'.format(res) return False target_datastore('foo.test') # instantiate foo.test's test driver res = testlib.ysi_REST_call('POST', '/v1/node/drivers/storage/test?index=1&force=1', None, api_pass='******') if 'error' in res or res['http_status'] != 200: print json.dumps(res, indent=4, sort_keys=True) return False res = testlib.ysi_cli_put_account("foo.test", "test", 'storage', "test:///index/index.manifest?diskroot=/tmp/ysi-integration-test-storage-foo.test", None, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to create foo.test account' print json.dumps(res, indent=4, sort_keys=True) return False os.makedirs('/tmp/ysi-integration-test-storage/mutable') os.makedirs('/tmp/ysi-integration-test-storage/immutable') shutil.copy("/tmp/ysi-integration-test-storage-foo.test/mutable/foo.test", "/tmp/ysi-integration-test-storage-bar.test/mutable/foo.test") shutil.copy("/tmp/ysi-integration-test-storage-foo.test/mutable/foo.test", "/tmp/ysi-integration-test-storage/mutable/foo.test") # link test account for bar.test # BUT! make sure we store the profile for bar.test into foo.test's and bar.test's storage directories! target_datastore('bar.test') # instantiate bar.test's test driver res = testlib.ysi_REST_call('POST', '/v1/node/drivers/storage/test?index=1&force=1', None, api_pass='******') if 'error' in res or res['http_status'] != 200: print json.dumps(res, indent=4, sort_keys=True) return False res = testlib.ysi_cli_put_account("bar.test", "test", 'storage', "test:///index/index.manifest?diskroot=/tmp/ysi-integration-test-storage-bar.test", None, wallet_keys=wallet_keys_2 ) if 'error' in res: res['test'] = 'Failed to create bar.test account' print json.dumps(res, indent=4, sort_keys=True) return False shutil.copy("/tmp/ysi-integration-test-storage-bar.test/mutable/bar.test", "/tmp/ysi-integration-test-storage-foo.test/mutable/bar.test") shutil.copy("/tmp/ysi-integration-test-storage-bar.test/mutable/bar.test", "/tmp/ysi-integration-test-storage/mutable/bar.test") # restore...we'll set up foo.test next res = testlib.ysi_test_setenv("TEST_BLOCKSTACK_TEST_DISK_ROOT", "/tmp/ysi-integration-test-storage-foo.test") if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) return False # get datastore keys... foo_datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() datastore_id_res = testlib.ysi_cli_datastore_get_id( foo_datastore_pk ) foo_datastore_id = datastore_id_res['datastore_id'] bar_datastore_pk = keylib.ECPrivateKey(wallets[-2].privkey).to_hex() datastore_id_res = testlib.ysi_cli_datastore_get_id( bar_datastore_pk ) bar_datastore_id = datastore_id_res['datastore_id'] # activate foo.test res = activate_account("foo.test", foo_datastore_pk) if not res: print 'failed to start API for bar.test: {}'.format(res) return False # set up foo.test's datastore res = setup_datastore(wallets[-1].privkey, "foo.test", 1) if not res: print 'failed to setup foo.test datastore' return False # activate bar.test res = activate_account("bar.test", bar_datastore_pk) if not res: print 'failed to start API for bar.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) print "\n\nbar.test tries to read foo.test's datastore {}\n\n".format(foo_datastore_id) res = read_datastore(foo_datastore_id, "foo.test", 1) if not res: print 'failed to read foo.test datastore {}'.format(foo_datastore_id) return False # set up bar.test's files res = setup_datastore(wallets[-2].privkey, 'bar.test', 2) if not res: print 'failed to setup bar.test datastore' return False # activate foo.test res = activate_account("foo.test", foo_datastore_pk) if not res: print 'failed to start API for foo.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # try to read all of bar.test's files print "\n\nfoo.test tries to read bar.test's datastore {}\n\n".format(bar_datastore_id) res = read_datastore(bar_datastore_id, 'bar.test', 2) if not res: print 'failed to read bar.test datastore {}'.format(bar_datastore_id) return False # re-target foo.test's datastore target_datastore('foo.test') # have foo.test write new files print '\n\nupdate foo.test datastore\n\n' res = write_datastore('foo.test', foo_datastore_pk, 3) if not res: print 'failed to update foo.test datastore {}'.format(foo_datastore_id) return False # activate bar.test res = activate_account("bar.test", bar_datastore_pk) if not res: print 'failed to start API for bar.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # get foo.test's new files res = read_datastore(foo_datastore_id, 'foo.test', 3) if not res: print 'failed to read new files from foo.test' return False # re-target bar.test's datastore target_datastore('bar.test') # have bar write some new files print '\n\nupdate bar.test datastore\n\n' res = write_datastore('bar.test', bar_datastore_pk, 4) if not res: print 'failed ot update bar.test datastore {}'.format(bar_datastore_id) return False # activate foo.test res = activate_account("foo.test", foo_datastore_pk) if not res: print 'failed to start API for foo.test: {}'.format(res) return False # delete foo's files print '\n\ndelete foo.test files\n\n' res = clear_datastore_files('foo.test', foo_datastore_pk) if not res: print 'failed to clear datastore {} for foo.test'.format(foo_datastore_id) return False # activate bar.test res = activate_account("bar.test", bar_datastore_pk) if not res: print 'failed to start API for bar.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # verify that foo's files are gone res = check_datastore_files_absent(foo_datastore_id, 'foo.test') if not res: print 'failed to verify that foo.test datastore {} is devoid of files'.format(foo_datastore_id) return False # re-target bar.test's datastore target_datastore('bar.test') # clear bar.test's files print '\n\ndelete bar.test files\n\n' res = clear_datastore_files('bar.test', bar_datastore_pk) if not res: print 'failed to clear datastore {} for bar.test'.format(bar_datastore_id) return False # activate foo.test res = activate_account("foo.test", foo_datastore_pk) if not res: print 'failed to start API for foo.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # verify that bar's files are gone res = check_datastore_files_absent(bar_datastore_id, 'bar.test') if not res: print 'failed to verify that bar.test datastore {} is devoid of files'.format(bar_datastore_id) return False # re-target foo.test's datastore target_datastore("foo.test") # clear foo's directories res = clear_datastore_directories('foo.test', foo_datastore_pk) if not res: print 'failed to clear foo.test datastore {} of directories'.format(foo_datastore_id) return False # activate bar.test res = activate_account("bar.test", bar_datastore_pk) if not res: print 'failed to start API for bar.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # verify that foo's directories are gone res = check_datastore_directories_absent(foo_datastore_id, "foo.test") if not res: print 'failed to verify that foo.test datastore {} is devoid of directories'.format(foo_datastore_id) return False # re-target bar.test's datastore target_datastore('bar.test') # clear bar's directories res = clear_datastore_directories('bar.test', bar_datastore_pk) if not res: print 'failed to clear bar.test datastore {} of directories'.format(bar_datastore_id) return False # activate foo.test res = activate_account('foo.test', foo_datastore_pk) if not res: print 'failed to start API for foo.test: {}'.format(res) return False # make *absolutely certain* that the test driver does not load data from # foo.test's or bar.test's storage directories. We want to verify that we can look up # the index manifest URLs from the profile target_datastore(None) # verify that bar's directories are gone res = check_datastore_directories_absent(bar_datastore_id, "bar.test") if not res: print 'failed to verify that bar.test datastore {} is devoid of directories'.format(bar_datastore_id) return False # root should be empty in both cases print 'listdir {} (bar.test)'.format('/') res = testlib.ysi_cli_datastore_listdir( 'bar.test', bar_datastore_id, '/', data_pubkeys=get_data_pubkeys('bar.test')) if 'error' in res: print 'failed to listdir / on bar.test: {}'.format(res['error']) return False if len(res['children'].keys()) > 0: print 'root still has children: {}'.format(res['children'].keys()) return False # activate bar.test res = activate_account('bar.test', bar_datastore_pk) if not res: print 'failed to start API for foo.test: {}'.format(res) return False print 'listdir {} (foo.test)'.format('/') res = testlib.ysi_cli_datastore_listdir( 'foo.test', foo_datastore_id, '/', data_pubkeys=get_data_pubkeys('foo.test')) if 'error' in res: print 'failed to listdir / on foo.test: {}'.format(res['error']) return False if len(res['children'].keys()) > 0: print 'root still has children: {}'.format(res['children'].keys()) return False testlib.next_block( **kw )
def scenario( wallets, **kw ): global put_result, wallet_keys, datasets, zonefile_hash, dataset_change wallet = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) resp = testlib.ysi_cli_register( "foo.test", "0123456789abcdef" ) if 'error' in resp: print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True) return False # wait for the preorder to get confirmed for i in xrange(0, 12): testlib.next_block( **kw ) # wait for the poller to pick it up print >> sys.stderr, "Waiting for the backend to submit the register" time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 12): testlib.next_block( **kw ) print >> sys.stderr, "Waiting for the backend to acknowledge registration" time.sleep(10) # wait for initial update to get confirmed for i in xrange(0, 12): # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) print >> sys.stderr, "Waiting for the backend to acknowledge update" time.sleep(10) # wait for zonefile/profile replication for i in xrange(0, 12): testlib.next_block( **kw ) print >> sys.stderr, "Waiting for the backend to replicate zonefile and profile" time.sleep(10) # make a few accounts res = testlib.ysi_cli_put_account("foo.test", "serviceFoo", "serviceFooID", "foo://bar.com", "0123456789abcdef", extra_data='foofield=foo!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test serviceFoo account' print json.dumps(res, indent=4, sort_keys=True) error = True return time.sleep(2) res = testlib.ysi_cli_put_account("foo.test", "serviceBar", "serviceBarID", "bar://baz.com", "0123456789abcdef", extra_data='barfield=bar!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test serviceBar account' print json.dumps(res, indent=4, sort_keys=True) error = True return time.sleep(2) # put some data put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_1", json.dumps(datasets[0]), password="******") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False testlib.next_block( **kw ) time.sleep(2) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_2", json.dumps(datasets[1]), password="******", \ storage_drivers=['ysi_server'], storage_drivers_exclusive=True) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_3", json.dumps(datasets[2]), password="******", \ storage_drivers=['ysi_server'], storage_drivers_exclusive=True) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) # increment data version too datasets[0]['buf'] = [] for i in xrange(0, 5): datasets[0]["dataset_change"] = dataset_change datasets[0]['buf'].append(i) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_1", json.dumps(datasets[0]), password="******", \ storage_drivers=['ysi_server'], storage_drivers_exclusive=True) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) return False time.sleep(2) testlib.next_block( **kw )
def scenario(wallets, **kw): global datasets, put_result, legacy_profile, data_history_1, data_history_2, data_history_3 testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # empty data testlib.ysi_name_update("foo.test", "00" * 20, wallets[3].privkey) data_history_1.append("missing zonefile") data_history_2.append("missing zonefile") data_history_3.append("missing zonefile") testlib.next_block(**kw) # set up legacy profile hash legacy_txt = json.dumps(legacy_profile, sort_keys=True) legacy_hash = virtualchain.lib.hashing.hex_hash160(legacy_txt) result = testlib.ysi_name_update("foo.test", legacy_hash, wallets[3].privkey) data_history_1.append("non-standard zonefile") data_history_2.append("non-standard zonefile") data_history_3.append("non-standard zonefile") testlib.next_block(**kw) rc = ysi_client.storage.put_immutable_data(legacy_txt, result['transaction_hash'], data_hash=legacy_hash) assert rc is not None # put immutable data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) # migrate profile res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) data_history_1.append("data not defined") data_history_2.append("data not defined") data_history_3.append("data not defined") testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False put_result = ysi_client.put_immutable("foo.test", "hello_world_1", json.dumps(datasets[0], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) data_history_1.append(put_result['immutable_data_hash']) data_history_2.append("data not defined") data_history_3.append("data not defined") # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) put_result = ysi_client.put_immutable("foo.test", "hello_world_2", json.dumps(datasets[1], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) data_history_1.append(data_history_1[-1]) data_history_2.append(put_result['immutable_data_hash']) data_history_3.append("data not defined") # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) put_result = ysi_client.put_immutable("foo.test", "hello_world_3", json.dumps(datasets[2], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) data_history_1.append(data_history_1[-1]) data_history_2.append(data_history_2[-1]) data_history_3.append(put_result['immutable_data_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) # overwrite datasets[0]['newdata'] = "asdf" put_result = ysi_client.put_immutable("foo.test", "hello_world_3", json.dumps(datasets[0], sort_keys=True), proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) data_history_1.append(data_history_1[-1]) data_history_2.append(data_history_2[-1]) data_history_3.append(put_result['immutable_data_hash']) del datasets[0]['newdata'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10)