desc: Tests meta queries for creating and deleting tables tests: - def: db = r.db('test') - cd: db.table_list() ot: [] - cd: r.db('rethinkdb').info() ot: ({'type':'DB','name':'rethinkdb','id':null}) - cd: r.db('rethinkdb').table('stats').info() ot: partial({'db':{'type':'DB','name':'rethinkdb','id':null}, 'type':'TABLE','id':null,'name':'stats', 'indexes':[],'primary_key':'id'}) # Table create - cd: db.table_create('a') ot: partial({'tables_created':1}) - cd: db.table_list() ot: ['a'] - cd: db.table_create('b') ot: partial({'tables_created':1}) - cd: db.table_list() ot: bag(['a', 'b']) # Table drop - cd: db.table_drop('a') ot: partial({'tables_dropped':1}) - cd: db.table_list() ot: ['b'] - cd: db.table_drop('b') ot: partial({'tables_dropped':1}) - cd: db.table_list() ot: [] # Table create options - py: db.table_create('ab', durability='soft') js: db.table_create('ab', {durability:'soft'}) rb: db.table_create('ab', :durability => 'soft') ot: partial({'tables_created':1,'config_changes':[partial({'new_val':partial({'durability':'soft'})})]}) - cd: db.table_drop('ab') ot: partial({'tables_dropped':1}) - py: db.table_create('ab', durability='hard') js: db.table_create('ab', {durability:'hard'}) rb: db.table_create('ab', :durability => 'hard') ot: partial({'tables_created':1,'config_changes':[partial({'new_val':partial({'durability':'hard'})})]}) - cd: db.table_drop('ab') ot: partial({'tables_dropped':1}) - py: db.table_create('ab', durability='fake') js: db.table_create('ab', {durability:'fake'}) rb: db.table_create('ab', :durability => 'fake') ot: err('ReqlQueryLogicError', 'Durability option `fake` unrecognized (options are "hard" and "soft").') - py: db.table_create('ab', primary_key='bar', shards=2, replicas=1) js: db.tableCreate('ab', {primary_key:'bar', shards:2, replicas:1}) rb: db.table_create('ab', {:primary_key => 'bar', :shards => 1, :replicas => 1}) ot: partial({'tables_created':1}) - cd: db.table_drop('ab') ot: partial({'tables_dropped':1}) - py: db.table_create('ab', primary_key='bar', primary_replica_tag='default') js: db.tableCreate('ab', {primary_key:'bar', primaryReplicaTag:'default'}) rb: db.table_create('ab', {:primary_key => 'bar', :primary_replica_tag => 'default'}) ot: partial({'tables_created':1}) - cd: db.table_drop('ab') ot: partial({'tables_dropped':1}) - py: db.table_create('ab', nonvoting_replica_tags=['default']) js: db.tableCreate('ab', {nonvotingReplicaTags:['default']}) rb: db.table_create('ab', {:nonvoting_replica_tags => ['default']}) ot: partial({'tables_created':1}) - cd: db.table_drop('ab') ot: partial({'tables_dropped':1}) # Table reconfigure - cd: db.table_create('a') ot: partial({'tables_created':1}) - py: db.table('a').reconfigure(shards=1, replicas=1) js: db.table('a').reconfigure({shards:1, replicas:1}) rb: db.table('a').reconfigure(:shards => 1, :replicas => 1) ot: partial({'reconfigured':1}) - py: db.table('a').reconfigure(shards=1, replicas={"default":1}, nonvoting_replica_tags=['default'], primary_replica_tag='default') js: db.table('a').reconfigure({shards:1, replicas:{default:1}, nonvoting_replica_tags:['default'], primary_replica_tag:'default'}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:default => 1}, :nonvoting_replica_tags => ['default'], :primary_replica_tag => 'default') ot: partial({'reconfigured':1}) - py: db.table('a').reconfigure(shards=1, replicas=1, dry_run=True) js: db.table('a').reconfigure({shards:1, replicas:1, dry_run:true}) rb: db.table('a').reconfigure(:shards => 1, :replicas => 1, :dry_run => true) ot: partial({'reconfigured':0}) - py: db.table('a').reconfigure(emergency_repair="unsafe_rollback") js: db.table('a').reconfigure({emergency_repair:"unsafe_rollback"}) rb: db.table('a').reconfigure(:emergency_repair => "unsafe_rollback") ot: err('ReqlOpFailedError', 'This table doesn\'t need to be repaired.', []) - py: db.table('a').reconfigure(emergency_repair="unsafe_rollback", dry_run=True) js: db.table('a').reconfigure({emergency_repair:"unsafe_rollback", dry_run:true}) rb: db.table('a').reconfigure(:emergency_repair => "unsafe_rollback", :dry_run => true) ot: err('ReqlOpFailedError', 'This table doesn\'t need to be repaired.', []) - py: db.table('a').reconfigure(emergency_repair="unsafe_rollback_or_erase") js: db.table('a').reconfigure({emergency_repair:"unsafe_rollback_or_erase"}) rb: db.table('a').reconfigure(:emergency_repair => "unsafe_rollback_or_erase") ot: err('ReqlOpFailedError', 'This table doesn\'t need to be repaired.', []) - py: db.table('a').reconfigure(emergency_repair=None, shards=1, replicas=1, dry_run=True) js: db.table('a').reconfigure({emergency_repair:null, shards:1, replicas:1, dry_run:true}) rb: db.table('a').reconfigure(:emergency_repair => null, :shards => 1, :replicas => 1, :dry_run => true) ot: partial({'reconfigured':0}) - cd: db.table_drop('a') ot: partial({'tables_dropped':1}) # Table errors - cd: db.table_create('foo') ot: partial({'tables_created':1}) - cd: db.table_create('foo') ot: err('ReqlOpFailedError', 'Table `test.foo` already exists.', [0]) - cd: db.table_drop('foo') ot: partial({'tables_dropped':1}) - cd: db.table_drop('foo') ot: err('ReqlOpFailedError', 'Table `test.foo` does not exist.', [0]) - cd: db.table_create('nonsense', 'foo') ot: js: err('ReqlCompileError', 'Expected 1 argument (not including options) but found 2.', []) rb: err("ReqlCompileError", "Expected between 1 and 2 arguments but found 3.", []) py: err("ReqlCompileError", "Expected between 1 and 2 arguments but found 3.", []) - js: db.table_create('nonsense', {'foo':'bar'}) py: db.table_create('nonsense', foo='bar') rb: db.table_create('nonsense', :foo => 'bar') ot: err('ReqlCompileError', "Unrecognized optional argument `foo`.", []) # RSI(reql_admin): Add tests for table_create() with configuration parameters # Table reconfigure errors - cd: db.table_create('a') ot: partial({'tables_created':1}) - py: db.table('a').reconfigure(shards=0, replicas=1) js: db.table('a').reconfigure({shards:0, replicas:1}) rb: db.table('a').reconfigure(:shards => 0, :replicas => 1) ot: err('ReqlQueryLogicError', 'Every table must have at least one shard.', []) - py: db.table('a').reconfigure(shards=1, replicas={"default":1}, primary_replica_tag="foo") js: db.table('a').reconfigure({shards:1, replicas:{default:1}, primary_replica_tag:"foo"}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:default => 1}, :primary_replica_tag => "foo") ot: err('ReqlOpFailedError', 'Can\'t use server tag `foo` for primary replicas because you specified no replicas in server tag `foo`.', []) - py: db.table('a').reconfigure(shards=1, replicas={"default":1}, primary_replica_tag="default", nonvoting_replica_tags=["foo"]) js: db.table('a').reconfigure({shards:1, replicas:{"default":1}, primary_replica_tag:"default", nonvoting_replica_tags:["foo"]}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:default => 1}, :primary_replica_tag => "default", :nonvoting_replica_tags => ["foo"]) ot: err('ReqlOpFailedError', 'You specified that the replicas in server tag `foo` should be non-voting, but you didn\'t specify a number of replicas in server tag `foo`.', []) - py: db.table('a').reconfigure(shards=1, replicas={"foo":0}, primary_replica_tag="foo") js: db.table('a').reconfigure({shards:1, replicas:{foo:0}, primary_replica_tag:"foo"}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:foo => 0}, :primary_replica_tag => "foo") ot: err('ReqlOpFailedError', 'You must set `replicas` to at least one. `replicas` includes the primary replica; if there are zero replicas, there is nowhere to put the data.', []) - py: db.table('a').reconfigure(shards=1, replicas={"default":0}) js: db.table('a').reconfigure({shards:1, replicas:{default:0}}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:default => 0}) ot: err('ReqlQueryLogicError', '`primary_replica_tag` must be specified when `replicas` is an OBJECT.', []) - py: db.table('a').reconfigure(shards=1, replicas={"default":-3}, primary_replica_tag='default') js: db.table('a').reconfigure({shards:1, replicas:{default:-3}, primary_replica_tag:'default'}) rb: db.table('a').reconfigure(:shards => 1, :replicas => {:default => -3}, :primary_replica_tag => 'default') ot: err('ReqlQueryLogicError', 'Can\'t have a negative number of replicas', []) - py: db.table('a').reconfigure(shards=1, replicas=3, primary_replica_tag='foo') js: db.table('a').reconfigure({shards:1, replicas:3, primary_replica_tag:'foo'}) rb: db.table('a').reconfigure(:shards => 1, :replicas => 3, :primary_replica_tag => 'foo') ot: err('ReqlQueryLogicError', '`replicas` must be an OBJECT if `primary_replica_tag` is specified.', []) - py: db.table('a').reconfigure(shards=1, replicas=3, nonvoting_replica_tags=['foo']) js: db.table('a').reconfigure({shards:1, replicas:3, nonvoting_replica_tags:['foo']}) rb: db.table('a').reconfigure(:shards => 1, :replicas => 3, :nonvoting_replica_tags => ['foo']) ot: err('ReqlQueryLogicError', '`replicas` must be an OBJECT if `nonvoting_replica_tags` is specified.', []) - py: db.reconfigure(emergency_repair="unsafe_rollback") js: db.reconfigure({emergency_repair:"unsafe_rollback"}) rb: db.reconfigure(:emergency_repair => "unsafe_rollback") ot: err('ReqlQueryLogicError', 'Can\'t emergency repair an entire database at once; instead you should run `reconfigure()` on each table individually.') - py: db.table('a').reconfigure(emergency_repair="foo") js: db.table('a').reconfigure({emergency_repair:"foo"}) rb: db.table('a').reconfigure(:emergency_repair => "foo") ot: err('ReqlQueryLogicError', '`emergency_repair` should be "unsafe_rollback" or "unsafe_rollback_or_erase"', []) - py: db.table('a').reconfigure(emergency_repair="unsafe_rollback", shards=1, replicas=1) js: db.table('a').reconfigure({emergency_repair:"unsafe_rollback", shards:1, replicas:1}) rb: db.table('a').reconfigure(:emergency_repair => "unsafe_rollback", :shards => 1, :replicas => 1) ot: err('ReqlQueryLogicError', 'In emergency repair mode, you can\'t specify shards, replicas, etc.') # Test reconfigure auto-sharding without data - py: db.table('a').reconfigure(shards=2, replicas=1) js: db.table('a').reconfigure({shards:2, replicas:1}) rb: db.table('a').reconfigure(:shards => 2, :replicas => 1) ot: partial({'reconfigured':1}) - py: db.table('a').wait(wait_for="all_replicas_ready") js: db.table('a').wait({"waitFor":"all_replicas_ready"}) rb: db.table('a').wait(:wait_for=>"all_replicas_ready") ot: {"ready":1} # Insert some data so that `reconfigure()` can pick shard points - py: db.table('a').insert([{"id":1}, {"id":2}, {"id":3}, {"id":4}]) js: db.table('a').insert([{id:1}, {id:2}, {id:3}, {id:4}]) rb: db.table('a').insert([{"id" => 1}, {"id" => 2}, {"id" => 3}, {"id" => 4}]) ot: partial({"inserted":4}) - py: db.table('a').reconfigure(shards=2, replicas=1) js: db.table('a').reconfigure({shards:2, replicas:1}) rb: db.table('a').reconfigure(:shards => 2, :replicas => 1) ot: partial({'reconfigured':1}) - py: db.table('a').reconfigure(shards=1, replicas=2) js: db.table('a').reconfigure({shards:1, replicas:2}) rb: db.table('a').reconfigure(:shards => 1, :replicas => 2) ot: err('ReqlOpFailedError', 'Can\'t put 2 replicas on servers with the tag `default` because there are only 1 servers with the tag `default`. It\'s impossible to have more replicas of the data than there are servers.', []) # Test wait and rebalance - py: db.table('a').wait(wait_for="all_replicas_ready") js: db.table('a').wait({"waitFor":"all_replicas_ready"}) rb: db.table('a').wait(:wait_for=>"all_replicas_ready") ot: {"ready":1} - cd: db.table('a').rebalance() ot: partial({'rebalanced':1}) - py: db.wait(wait_for="all_replicas_ready") js: db.wait({"waitFor":"all_replicas_ready"}) rb: db.wait(:wait_for=>"all_replicas_ready") ot: {"ready":1} - cd: db.rebalance() ot: partial({'rebalanced':1}) - cd: r.wait() ot: py: err('AttributeError', "'module' object has no attribute 'wait'", []) # different sub-versions of node have different messages #5617 js: err('TypeError') rb: err('ReqlQueryLogicError', '`wait` can only be called on a table or database.', []) - cd: r.rebalance() ot: py: err('AttributeError', "'module' object has no attribute 'rebalance'", []) # different sub-versions of node have different messages #5617 js: err('TypeError') rb: err('ReqlQueryLogicError', '`rebalance` can only be called on a table or database.', []) - cd: db.table_drop('a') ot: partial({'tables_dropped':1}) # Reconfiguring all tables in a database - cd: db.table_create('a') - cd: db.table_create('b') - cd: db.table_create('c') - py: db.reconfigure(shards=0, replicas=1) js: db.reconfigure({shards:0, replicas:1}) rb: db.reconfigure(:shards => 0, :replicas => 1) ot: err('ReqlQueryLogicError', 'Every table must have at least one shard.', []) - py: db.reconfigure(shards=1, replicas={"default":0}) js: db.reconfigure({shards:1, replicas:{default:0}}) rb: db.reconfigure(:shards => 1, :replicas => {:default => 0}) ot: err('ReqlQueryLogicError', '`primary_replica_tag` must be specified when `replicas` is an OBJECT.', []) - py: db.reconfigure(shards=1, replicas={"default":-3}, primary_replica_tag='default') js: db.reconfigure({shards:1, replicas:{default:-3}, primary_replica_tag:'default'}) rb: db.reconfigure(:shards => 1, :replicas => {:default => -3}, :primary_replica_tag => 'default') ot: err('ReqlQueryLogicError', 'Can\'t have a negative number of replicas', []) - py: db.reconfigure(shards=1, replicas=3, primary_replica_tag='foo') js: db.reconfigure({shards:1, replicas:3, primary_replica_tag:'foo'}) rb: db.reconfigure(:shards => 1, :replicas => 3, :primary_replica_tag => 'foo') ot: err('ReqlQueryLogicError', '`replicas` must be an OBJECT if `primary_replica_tag` is specified.', []) - py: db.reconfigure(shards=2, replicas=1) js: db.reconfigure({shards:2, replicas:1}) rb: db.reconfigure(:shards => 2, :replicas => 1) ot: partial({'reconfigured':3}) - cd: db.table_drop('a') ot: partial({'tables_dropped':1}) - cd: db.table_drop('b') ot: partial({'tables_dropped':1}) - cd: db.table_drop('c') ot: partial({'tables_dropped':1}) # table_config and table_status porcelains - cd: r.db_create("test2") ot: partial({'dbs_created':1}) - def: db2 = r.db("test2") - cd: db.table_create("testA") ot: partial({'tables_created':1}) - cd: db.table_create("testB") ot: partial({'tables_created':1}) - cd: db2.table_create("test2B") ot: partial({'tables_created':1}) - cd: r.table('testA').config().pluck('db','name') ot: {'db':'test','name':'testA'} - cd: r.table('doesntexist').config() ot: err('ReqlOpFailedError', 'Table `test.doesntexist` does not exist.', []) - cd: r.table('test2B').config() ot: err('ReqlOpFailedError', 'Table `test.test2B` does not exist.', []) - cd: r.db('rethinkdb').table('table_config').filter({'name':'testA'}).nth(0).eq(r.table('testA').config()) ot: True - cd: r.db('rethinkdb').table('table_status').filter({'name':'testA'}).nth(0).eq(r.table('testA').status()) ot: True - py: r.db('rethinkdb').table('table_config', identifier_format='uuid').nth(0)["db"] js: r.db('rethinkdb').table('table_config', {identifierFormat:'uuid'}).nth(0)("db") rb: r.db('rethinkdb').table('table_config', {:identifier_format=>'uuid'}).nth(0)["db"] ot: uuid() - py: r.table('testA', identifier_format='uuid').count() js: r.table('testA', {identifierFormat:'uuid'}).count() rb: r.table('testA', {:identifier_format=>'uuid'}).count() ot: 0 - py: r.wait(wait_for='all_replicas_ready', timeout=5) js: r.wait({waitFor:'all_replicas_ready', timeout:5}) rb: r.wait(:wait_for=>'all_replicas_ready', :timeout => 5) ot: py: err('AttributeError', "'module' object has no attribute 'wait'", []) # different sub-versions of node have different messages #5617 js: err('TypeError') rb: err('ReqlQueryLogicError', '`wait` can only be called on a table or database.', []) - cd: db.table_drop('testA') ot: partial({'tables_dropped':1}) - cd: db.table_drop('testB') ot: partial({'tables_dropped':1}) - cd: r.db_drop('test2') ot: partial({'dbs_dropped':1,'tables_dropped':1})