diff options
author | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2020-02-28 11:41:02 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-03-02 15:16:53 +0000 |
commit | f44bfe5d2fa808b299c5bc83979138b5eb6df6be (patch) | |
tree | d56d4c1b0efe67b82f5dce09895b3570350bf619 | |
parent | ef1f4cd07d03aeb540072602416eba5b5980c4bd (diff) | |
download | mongo-f44bfe5d2fa808b299c5bc83979138b5eb6df6be.tar.gz |
SERVER-37148 Remove mr_shard_version.js and mr_during_migrate.js in favor of MR FSM test
19 files changed, 118 insertions, 200 deletions
diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml index b66e57dbd84..6d61fb61b8a 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml @@ -37,6 +37,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml index f09441b5100..d7748fccc5d 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency_and_balancer.yml @@ -40,6 +40,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_kill_primary_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_kill_primary_with_balancer.yml index a151e01e6fb..4222602202f 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_kill_primary_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_kill_primary_with_balancer.yml @@ -37,6 +37,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn.yml index 068e4b1e702..385853c717c 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn.yml @@ -38,6 +38,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn_with_balancer.yml index 736cb788977..a12e007c5fe 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn_with_balancer.yml @@ -38,6 +38,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn.yml index 1c4c912fafd..90f177fb45e 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn.yml @@ -38,6 +38,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_kill_primary.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_kill_primary.yml index eaec2f94d69..6f708ebc507 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_kill_primary.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_kill_primary.yml @@ -43,6 +43,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_terminate_primary.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_terminate_primary.yml index be56c7f0336..110a73c44ac 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_terminate_primary.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_terminate_primary.yml @@ -43,6 +43,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_balancer.yml index 6cca950b4b9..a5b7b103245 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_balancer.yml @@ -38,6 +38,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_stepdowns.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_stepdowns.yml index 93e13a1a6f8..8ffa52c46bf 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_stepdowns.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_stepdowns.yml @@ -43,6 +43,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml index f668fc305a6..5e8574daf11 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml @@ -34,6 +34,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml index 9d9b0a01d10..b6092f086c8 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_replication_with_balancer.yml @@ -37,6 +37,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_terminate_primary_with_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_terminate_primary_with_balancer.yml index 4442d58c5ca..0dbc021c7b4 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_terminate_primary_with_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_terminate_primary_with_balancer.yml @@ -37,6 +37,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml index 6aeb4648258..e1357e2d370 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml @@ -34,6 +34,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml index fdf352fc9ad..1d6faa84dbe 100644 --- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml +++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml @@ -37,6 +37,7 @@ selector: - jstests/concurrency/fsm_workloads/map_reduce_replace.js - jstests/concurrency/fsm_workloads/map_reduce_replace_nonexistent.js - jstests/concurrency/fsm_workloads/map_reduce_replace_remove.js + - jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js # Disabled due to MongoDB restrictions and/or workload restrictions diff --git a/buildscripts/resmokeconfig/suites/sharding_misc.yml b/buildscripts/resmokeconfig/suites/sharding_misc.yml index 913ce2e5ba6..3a56166309c 100644 --- a/buildscripts/resmokeconfig/suites/sharding_misc.yml +++ b/buildscripts/resmokeconfig/suites/sharding_misc.yml @@ -73,7 +73,6 @@ selector: - jstests/sharding/move_chunk_remove_with_write_retryability.js - jstests/sharding/move_chunk_update_with_write_retryability.js - jstests/sharding/addshard2.js - - jstests/sharding/mr_shard_version.js - jstests/sharding/move_chunk_insert_with_write_retryability.js - jstests/sharding/safe_secondary_reads_single_migration_waitForDelete.js - jstests/sharding/replmonitor_bad_seed.js diff --git a/jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js b/jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js new file mode 100644 index 00000000000..3c5fb384026 --- /dev/null +++ b/jstests/concurrency/fsm_workloads/map_reduce_with_chunk_migrations.js @@ -0,0 +1,103 @@ +'use strict'; + +/** + * map_reduce_with_chunk_migrations.js + * + * This tests exercises mapReduce on a collection during chunk migrations. If extending this + * workload, consider overriding the following: + * + * $config.data.collWithMigrations: collection to run chunk migrations against (default is the + * input collection of the mapReduce). + * $config.state.mapReduce: function to execute the mapReduce. + * + * @tags: [ + * requires_sharding, assumes_balancer_off, + * assumes_autosplit_off, + * requires_non_retryable_writes, + * # mapReduce does not support afterClusterTime. + * does_not_support_causal_consistency, + * ] + */ +load('jstests/concurrency/fsm_libs/extend_workload.js'); // for extendWorkload +load('jstests/concurrency/fsm_workloads/sharded_moveChunk_partitioned.js'); // for $config + +var $config = extendWorkload($config, function($config, $super) { + // The base setup will insert 'partitionSize' number of documents per thread, evenly + // distributing across the chunks. Documents will only have the "_id" field. + $config.data.partitionSize = 50; + $config.threadCount = 2; + $config.iterations = 100; + $config.data.numDocs = $config.data.partitionSize * $config.threadCount; + + // By default, the collection that will be sharded with concurrent chunk migrations will be the + // one that the aggregate is run against. + $config.data.collWithMigrations = $config.collName; + + $config.transitions = { + init: {mapReduce: 1}, + mapReduce: { + moveChunk: 0.2, + mapReduce: 0.8, + }, + moveChunk: {mapReduce: 1}, + }; + + /** + * Moves a random chunk in the target collection. + */ + $config.states.moveChunk = function moveChunk(db, collName, connCache) { + $super.states.moveChunk.apply(this, [db, this.collWithMigrations, connCache]); + }; + + /** + * Executes a mapReduce with output mode "replace". + */ + $config.states.mapReduce = function mapReduce(db, collName, connCache) { + const map = function() { + emit(this._id, 1); + }; + const reduce = function(k, values) { + return Array.sum(values); + }; + + const res = db[collName].mapReduce(map, reduce, {out: {replace: this.resultsCollection}}); + assertWhenOwnColl.commandWorked(res); + + assert.eq(this.numDocs, db[this.resultsCollection].find().itcount()); + }; + + /** + * Uses the base class init() to initialize this thread for both collections. + */ + $config.states.init = function init(db, collName, connCache) { + $super.states.init.apply(this, [db, collName, connCache]); + + // Init the target collection in a similar manner, if it is different than the default + // collection. + if (collName != this.collWithMigrations) { + $super.states.init.apply(this, [db, this.collWithMigrations, connCache]); + } + + // Use a unique target collection name per thread to avoid colliding during the final rename + // of the mapReduce. + this.resultsCollection = "map_reduce_with_chunk_migrations_out_" + this.tid; + }; + + /** + * Initializes the aggregate collection and the target collection for chunk migrations as + * sharded with an even distribution across each thread ID. + */ + $config.setup = function setup(db, collName, cluster) { + $super.setup.apply(this, [db, collName, cluster]); + + if (collName != this.collWithMigrations) { + // Setup the target collection in a similar manner. Note that the FSM infrastructure + // will have already enabled sharded on collName, but we need to manually do it for the + // output collection. + cluster.shardCollection(db[this.collWithMigrations], this.shardKey, false); + $super.setup.apply(this, [db, this.collWithMigrations, cluster]); + } + }; + + return $config; +}); diff --git a/jstests/sharding/mr_shard_version.js b/jstests/sharding/mr_shard_version.js deleted file mode 100644 index 52622b4ce66..00000000000 --- a/jstests/sharding/mr_shard_version.js +++ /dev/null @@ -1,87 +0,0 @@ -// Test for SERVER-4158 (version changes during mapreduce) -(function() { - -var st = new ShardingTest({shards: 2, mongos: 1}); - -// Stop balancer, since it'll just get in the way of these -st.stopBalancer(); - -var coll = st.s.getCollection(jsTest.name() + ".coll"); - -var numDocs = 50000; -var numKeys = 1000; -var numTests = 3; - -var bulk = coll.initializeUnorderedBulkOp(); -for (var i = 0; i < numDocs; i++) { - bulk.insert({_id: i, key: "" + (i % numKeys), value: i % numKeys}); -} -assert.writeOK(bulk.execute()); - -assert.eq(numDocs, coll.find().itcount()); - -var halfId = coll.find().itcount() / 2; - -// Shard collection in half -st.shardColl(coll, {_id: 1}, {_id: halfId}); - -st.printShardingStatus(); - -jsTest.log("Collection now initialized with keys and values..."); - -jsTest.log("Starting migrations..."); - -var ops = {}; -for (var i = 0; i < st._connections.length; i++) { - for (var j = 0; j < 2; j++) { - ops["" + (i * 2 + j)] = { - op: "command", - ns: "admin", - command: { - moveChunk: "" + coll, - find: {_id: (j == 0 ? 0 : halfId)}, - to: st._connections[i].shardName - }, - }; - } -} - -var bid = benchStart({ops: ops, host: st.s.host, parallel: 1, handleErrors: false}); - -jsTest.log("Starting m/r..."); - -var map = function() { - emit(this.key, this.value); -}; -var reduce = function(k, values) { - var total = 0; - for (var i = 0; i < values.length; i++) - total += values[i]; - return total; -}; - -var outputColl = st.s.getCollection(jsTest.name() + ".mrOutput"); - -jsTest.log("Output coll : " + outputColl); - -for (var t = 0; t < numTests; t++) { - var results = coll.mapReduce(map, reduce, {out: {replace: outputColl.getName()}}); - - // Assert that the results are actually correct, all keys have values of (numDocs / numKeys) - // x key - var output = outputColl.find().sort({_id: 1}).toArray(); - - // printjson( output ) - - assert.eq(output.length, numKeys); - printjson(output); - for (var i = 0; i < output.length; i++) - assert.eq(parseInt(output[i]._id) * (numDocs / numKeys), output[i].value); -} - -jsTest.log("Finishing parallel migrations..."); - -printjson(benchFinish(bid)); - -st.stop(); -})(); diff --git a/jstests/slow1/mr_during_migrate.js b/jstests/slow1/mr_during_migrate.js deleted file mode 100644 index 06d79c46e92..00000000000 --- a/jstests/slow1/mr_during_migrate.js +++ /dev/null @@ -1,112 +0,0 @@ -// Do parallel ops with migrates occurring -// @tags: [requires_sharding] - -(function() { -'use strict'; - -var st = new ShardingTest({shards: 10, mongos: 2, verbose: 2}); - -var mongos = st.s0; -var admin = mongos.getDB("admin"); -var coll = st.s.getCollection(jsTest.name() + ".coll"); - -var numDocs = 1024 * 1024; -var dataSize = 1024; // bytes, must be power of 2 - -var data = "x"; -while (data.length < dataSize) - data += data; - -var bulk = coll.initializeUnorderedBulkOp(); -for (var i = 0; i < numDocs; i++) { - bulk.insert({_id: i, data: data}); -} -assert.writeOK(bulk.execute()); - -// Make sure everything got inserted -assert.eq(numDocs, coll.find().itcount()); - -jsTest.log("Inserted " + sh._dataFormat(dataSize * numDocs) + " of data."); - -// Shard collection -st.shardColl(coll, {_id: 1}, false); - -st.printShardingStatus(); - -jsTest.log("Sharded collection now initialized, starting migrations..."); - -var checkMigrate = function() { - print("Result of migrate : "); - printjson(this); -}; - -// Creates a number of migrations of random chunks to diff shard servers -var ops = []; -for (var i = 0; i < st._connections.length; i++) { - ops.push({ - op: "command", - ns: "admin", - command: { - moveChunk: "" + coll, - find: {_id: {"#RAND_INT": [0, numDocs]}}, - to: st._connections[i].shardName, - _waitForDelete: true - }, - showResult: true - }); -} - -// TODO: Also migrate output collection - -jsTest.log("Starting migrations now..."); - -var bid = benchStart({ops: ops, host: st.s.host, parallel: 1, handleErrors: false}); - -//####################### -// Tests during migration - -var numTests = 5; - -for (var t = 0; t < numTests; t++) { - jsTest.log("Test #" + t); - - var mongos = st.s1; // use other mongos so we get stale shard versions - var coll = mongos.getCollection(coll + ""); - var outputColl = mongos.getCollection(coll + "_output"); - - var numTypes = 32; - var map = function() { - emit(this._id % 32 /* must be hardcoded */, {c: 1}); - }; - - var reduce = function(k, vals) { - var total = 0; - for (var i = 0; i < vals.length; i++) - total += vals[i].c; - return {c: total}; - }; - - printjson(coll.find({_id: 0}).itcount()); - - jsTest.log("Starting new mapReduce run #" + t); - - // assert.eq( coll.find().itcount(), numDocs ) - - coll.getMongo().getDB("admin").runCommand({setParameter: 1, traceExceptions: true}); - - printjson(coll.mapReduce( - map, reduce, {out: {replace: outputColl.getName(), db: outputColl.getDB() + ""}})); - - jsTest.log("MapReduce run #" + t + " finished."); - - assert.eq(outputColl.find().itcount(), numTypes); - - outputColl.find().forEach(function(x) { - assert.eq(x.value.c, numDocs / numTypes); - }); -} - -printjson(benchFinish(bid)); - -st.stop(); -})(); |