def write_datastore(blockchain_id, datastore_pk, iteration): """ write some files to the datastore, over existing ones """ global sessions ses = sessions[blockchain_id] # put files again! for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'putfile {}'.format(dpath) data = '{} hello {} {}'.format(file_data, iteration, dpath) res = testlib.ysi_cli_datastore_putfile( blockchain_id, datastore_pk, dpath, data, ses) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False return True
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 put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2, immutable_hash, datastore_name wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[8].privkey, wallets[3].privkey, wallets[4].privkey) wallet_keys_2 = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[9].privkey, wallets[6].privkey, wallets[7].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) 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) # set up legacy profile hash legacy_txt = json.dumps(legacy_profile, sort_keys=True) legacy_hash = pybitcoin.hex_hash160(legacy_txt) result_1 = testlib.ysi_name_update("foo.test", legacy_hash, wallets[3].privkey) result_2 = testlib.ysi_name_update("bar.test", legacy_hash, wallets[6].privkey) testlib.next_block(**kw) rc = ysi_client.storage.put_immutable_data(None, result_1['transaction_hash'], data_hash=legacy_hash, data_text=legacy_txt) assert rc is not None rc = ysi_client.storage.put_immutable_data(None, result_2['transaction_hash'], data_hash=legacy_hash, data_text=legacy_txt) assert rc is not None testlib.next_block(**kw) # migrate 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 else: zonefile_hash = res['zonefile_hash'] # migrate res = testlib.migrate_profile("bar.test", proxy=test_proxy, wallet_keys=wallet_keys_2) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return else: zonefile_hash_2 = res['zonefile_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) # start up RPC for 'foo.test' testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # put immutable put_result = testlib.ysi_cli_put_immutable("foo.test", "hello_world_immutable", json.dumps({'hello': 'world'}), password='******') log.debug("put immutable for foo.test") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) error = True return immutable_hash = put_result['immutable_data_hash'] 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 confirmation for i in xrange(0, 12): testlib.next_block(**kw) print "waiting for confirmation" time.sleep(10) # start up RPC for 'bar.test' testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey']) log.debug("put mutable for bar.test") put_result = testlib.ysi_cli_put_mutable('bar.test', 'hello_world_mutable', json.dumps({'hello': 'world'}), password='******') if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False testlib.next_block(**kw) # put mutable data again testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) res = testlib.ysi_cli_put_mutable('foo.test', 'foo_data2', json.dumps({'hello2': 'world2'}), password='******') if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) return False # put immutable data with the URL # start up RPC for 'foo.test' log.debug("put immutable for foo.test (2)") res = testlib.ysi_cli_put_immutable('foo.test', 'foo_immutable', json.dumps({'hello3': 'world3'}), password='******') if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) 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) datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() datastore_id_res = testlib.ysi_cli_datastore_get_id(datastore_pk) datastore_name = datastore_id_res['datastore_id'] # make datastore res = testlib.ysi_cli_create_datastore(datastore_pk) if 'error' in res: print "failed to create datastore: {}".format(res['error']) return False # put a file into the datastore data = 'hello datastore' log.debug("putfile") res = testlib.ysi_cli_datastore_putfile(datastore_pk, '/hello_datastore', data) if 'error' in res: print 'failed to putfile /hello_datastore: {}'.format(res['error']) return False # make a directory log.debug("mkdir") res = testlib.ysi_cli_datastore_mkdir(datastore_pk, '/hello_dir') if 'error' in res: print 'failed to mkdir /hello_dir: {}'.format(res['error']) return False # put a file into the directory data = 'hello dir datastore' log.debug("putfile in dir") res = testlib.ysi_cli_datastore_putfile(datastore_pk, '/hello_dir/hello_dir_datastore', data) if 'error' in res: print 'failed to putfile /hello_dir/hello_dir_datastore: {}'.format( res['error']) return False testlib.next_block(**kw)