def test_should_take_if_model_price_updated(self, kick): # given (model, model_factory) = models(self.keeper, kick) (needs_redo, price, initial_lot, initial_tab) = self.clipper.status(kick) # when initial model price is too low bad_price = price - Ray.from_number(30) self.simulate_model_bid(model, bad_price) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then ensure no bid was submitted (needs_redo, price, lot, tab) = self.clipper.status(kick) assert lot == initial_lot assert tab == initial_tab # when model price becomes appropriate good_price = price + Ray.from_number(30) self.simulate_model_bid(model, good_price) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then ensure our bid was submitted our_take: Clipper.TakeLog = self.last_log() assert our_take.id == kick assert our_take.price <= good_price # and that the auction finished (needs_redo, price, lot, tab) = self.clipper.status(kick) assert not needs_redo assert lot == Wad(0) or tab == Rad(0)
def test_should_overbid_itself_if_model_has_updated_the_price(self, kick): # given (model, model_factory) = models(self.keeper, kick) lot = self.flapper.bids(kick).lot # when first_bid = Wad.from_number(0.0000004) simulate_model_output(model=model, price=first_bid) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.flapper.bids(kick).bid == Wad(lot / Rad(first_bid)) # when second_bid = Wad.from_number(0.0000003) simulate_model_output(model=model, price=second_bid) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.flapper.bids(kick).bid == Wad(lot / Rad(second_bid)) # cleanup time_travel_by(self.web3, self.flapper.ttl() + 1) assert self.flapper.deal(kick).transact()
def test_should_not_bid_on_rounding_errors_with_small_amounts(self, kick): # given (model, model_factory) = models(self.keeper, kick) lot = self.flapper.bids(kick).lot # when price = Wad.from_number(9.0)-Wad(5) simulate_model_output(model=model, price=price) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.flapper.bids(kick).bid == Wad(lot) / Wad(price) # when tx_count = self.web3.eth.getTransactionCount(self.keeper_address.address) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getTransactionCount(self.keeper_address.address) == tx_count # cleanup time_travel_by(self.web3, self.flapper.ttl() + 1) assert self.flapper.deal(kick).transact()
def test_should_not_tend_on_rounding_errors_with_small_amounts( self, mcd, c, kick_small_lot, keeper): # given (model, model_factory) = models(keeper, kick_small_lot) flipper = c.flipper # when bid_price = Wad.from_number(3.0) self.simulate_model_bid(mcd, c, model, bid_price) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert flipper.bids(kick_small_lot).bid == Rad(bid_price * tend_small_lot) # when tx_count = self.web3.eth.getTransactionCount( self.keeper_address.address) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getTransactionCount( self.keeper_address.address) == tx_count
def test_should_tick_if_auction_expired_due_to_tau(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when time_travel_by(self.web3, self.flapper.tau() + 1) # and simulate_model_output(model=model, price=Wad.from_number(9.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then model.terminate.assert_not_called() auction = self.flapper.bids(kick) assert round(Wad(auction.lot) / auction.bid, 2) == round(Wad.from_number(9.0), 2) # cleanup time_travel_by(self.web3, self.flapper.ttl() + 1) model_factory.create_model.assert_called_once() self.keeper.check_all_auctions() model.terminate.assert_called_once()
def test_should_use_most_up_to_date_price_for_dent_even_if_it_gets_updated_during_tend( self, mcd, c, kick, keeper, keeper_address): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when first_bid_price = Wad.from_number(140) self.simulate_model_bid(mcd, c, model, first_bid_price) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then auction = flipper.bids(kick) assert auction.bid == auction.tab assert auction.lot == tend_lot # when second_bid_price = Wad.from_number(150) self.simulate_model_bid(mcd, c, model, second_bid_price) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() auction = flipper.bids(kick) assert auction.bid == auction.tab assert auction.lot == Wad(auction.bid / Rad(second_bid_price)) # cleanup time_travel_by(self.web3, flipper.ttl() + 1) assert flipper.deal(kick).transact()
def test_should_overbid_itself_if_model_has_updated_the_price( self, mcd, c, kick, keeper, keeper_address): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when first_bid = Wad.from_number(15.0) self.simulate_model_bid(mcd, c, model, first_bid) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert flipper.bids(kick).bid == Rad(first_bid * tend_lot) # when second_bid = Wad.from_number(20.0) self.simulate_model_bid(mcd, c, model, second_bid) keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert flipper.bids(kick).bid == Rad(second_bid * tend_lot) # cleanup time_travel_by(self.web3, flipper.ttl() + 1) assert flipper.deal(kick).transact()
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_start( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once_with( Parameters(collateral_auction_house=None, surplus_auction_house=None, debt_auction_house=self.debt_auction_house.address, staked_token_auction_house=None, id=auction_id)) # and status = model.send_status.call_args[0][0] assert status.id == auction_id assert status.collateral_auction_house is None assert status.surplus_auction_house is None assert status.debt_auction_house == self.debt_auction_house.address assert status.bid_amount > Rad.from_number(0) assert status.amount_to_sell == self.geb.accounting_engine.initial_debt_auction_minted_tokens( ) assert status.amount_to_raise is None assert status.bid_decrease > Wad.from_number(1) assert status.high_bidder == self.geb.accounting_engine.address assert status.block_time > 0 assert status.auction_deadline < status.block_time + self.debt_auction_house.total_auction_length( ) + 1 assert status.bid_expiry == 0 assert status.price == Wad(status.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(status.amount_to_sell))
def test_should_restart_auction_if_auction_expired_due_to_total_auction_length( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when time_travel_by(self.web3, self.debt_auction_house.total_auction_length() + 1) # and simulate_model_output(model=model, price=Wad.from_number(555.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then model.terminate.assert_not_called() auction = self.debt_auction_house.bids(auction_id) assert round( auction.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(auction.amount_to_sell), 2) == round(Rad.from_number(555.0), 2) # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) model_factory.create_model.assert_called_once() self.keeper.check_all_auctions() model.terminate.assert_called_once()
def test_should_overbid_itself_if_model_has_updated_the_price(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when simulate_model_output(model=model, price=Wad.from_number(100.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert round(Rad(self.flopper.bids(kick).lot), 2) == round(self.sump / Rad.from_number(100.0), 2) # when simulate_model_output(model=model, price=Wad.from_number(110.0)) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.lot_implies_price(kick, Wad.from_number(110.0)) # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) assert self.flopper.deal(kick).transact()
def test_should_increase_gas_price_of_pending_transactions_if_model_increases_gas_price( self, kick): # given (model, model_factory) = models(self.keeper, kick) # when simulate_model_output(model=model, price=Wad.from_number(120.0), gas_price=10) # and self.start_ignoring_transactions() # and self.keeper.check_all_auctions() self.keeper.check_for_bids() # and time.sleep(2) # and self.end_ignoring_transactions() # and simulate_model_output(model=model, price=Wad.from_number(120.0), gas_price=15) # and self.keeper.check_for_bids() wait_for_other_threads() # then assert self.lot_implies_price(kick, Wad.from_number(120.0)) assert self.web3.eth.getBlock( 'latest', full_transactions=True).transactions[0].gasPrice == 15 # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) assert self.flopper.deal(kick).transact()
def test_should_bid_even_if_there_is_already_a_bidder(self, kick): # given (model, model_factory) = models(self.keeper, kick) mkr_before = self.mcd.mkr.balance_of(self.keeper_address) # and lot = Wad.from_number(0.000016) assert self.flopper.dent( kick, lot, self.sump).transact(from_address=self.other_address) assert self.flopper.bids(kick).lot == lot # when simulate_model_output(model=model, price=Wad.from_number(825.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then auction = self.flopper.bids(kick) assert auction.lot != lot assert round(auction.bid / Rad(auction.lot), 2) == round(Rad.from_number(825.0), 2) mkr_after = self.mcd.mkr.balance_of(self.keeper_address) assert mkr_before == mkr_after # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) assert self.flopper.deal(kick).transact()
def test_should_terminate_model_if_auction_expired_due_to_ttl_and_somebody_else_won_it( self, kick): # given (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when self.dent(kick, self.other_address, Wad.from_number(0.000015), self.sump) # and time_travel_by(self.web3, self.flopper.ttl() + 1) # and self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once() # cleanup assert self.flopper.deal(kick).transact()
def test_should_take_partial_if_insufficient_dai_available(self, kick): # given (model, model_factory) = models(self.keeper, kick) (needs_redo, price, initial_lot, initial_tab) = self.clipper.status(kick) assert initial_lot == Wad.from_number(1) # and we exit all Dai out of the Vat assert self.mcd.dai_adapter.exit(self.keeper_address, Wad(self.mcd.vat.dai(self.keeper_address)))\ .transact(from_address=self.keeper_address) # when we have less Dai than we need to cover the auction our_price = Ray.from_number(187) assert our_price < price dai_needed = initial_lot * Wad(our_price) half_dai = dai_needed / Wad.from_number(2) initial_dai_balance = Wad(self.mcd.vat.dai(self.keeper_address)) if initial_dai_balance < half_dai: print(f"Reserving {half_dai - initial_dai_balance} Dai to get balance of {half_dai}") reserve_dai(self.mcd, self.dai_collateral, self.keeper_address, half_dai - initial_dai_balance) else: print(f"Abandoning {initial_dai_balance - half_dai} Dai to get balance of {half_dai}") self.mcd.vat.move(self.keeper_address, self.gal_address, Rad(initial_dai_balance - half_dai))\ .transact(from_address=keeper_address) dai_balance_before_take = Wad(self.mcd.vat.dai(self.keeper_address)) assert Wad(0) < dai_balance_before_take < dai_needed # then ensure we don't bid when the price is too high self.simulate_model_bid(model, our_price, reserve_dai_for_bid=False) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() (needs_redo, price, lot, tab) = self.clipper.status(kick) assert lot == initial_lot assert tab == initial_tab # when we wait for the price to become appropriate while lot > Wad(0): time_travel_by(self.web3, 1) (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) if auction_price < our_price: break # then ensure our bid is submitted using available Dai # self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() (needs_redo, price, lot, tab) = self.clipper.status(kick) assert Wad(0) < lot < initial_lot our_take = self.last_log() assert isinstance(our_take, Clipper.TakeLog) assert Wad(self.mcd.vat.dai(self.keeper_address)) < dai_balance_before_take # and ensure we don't place a subsequent dusty bid afterward self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() our_take2 = self.last_log() assert our_take.tx_hash == our_take2.tx_hash # cleanup self.take_below_price(kick, price, self.keeper_address)
def test_should_terminate_model_if_auction_expired_due_to_ttl_and_somebody_else_won_it( self, mcd, c, kick, other_address, keeper): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when flipper.approve( flipper.vat(), approval_function=hope_directly(from_address=other_address)) new_bid_amount = Rad.from_number(85) self.tend_with_dai(mcd, c, flipper, kick, other_address, new_bid_amount) # and time_travel_by(self.web3, flipper.ttl() + 1) # and keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once() # cleanup assert flipper.deal(kick).transact()
def test_should_terminate_model_if_auction_is_settled(self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when self.decrease_sold_amount(auction_id, self.other_address, Wad.from_number(0.000016), self.debt_auction_bid_size) # and time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) # and self.debt_auction_house.settle_auction(auction_id).transact( from_address=self.other_address) # and self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once()
def test_should_terminate_model_if_auction_is_dealt( self, mcd, c, kick, other_address, keeper): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when self.tend_with_dai(mcd, c, flipper, kick, other_address, Rad.from_number(90)) # and time_travel_by(self.web3, flipper.ttl() + 1) # and flipper.deal(kick).transact(from_address=other_address) # and keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once()
def test_should_bid_even_if_there_is_already_a_bidder(self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) prot_before = self.geb.prot.balance_of(self.keeper_address) # and amount_to_sell = Wad.from_number(0.000016) assert self.debt_auction_house.decrease_sold_amount( auction_id, amount_to_sell, self.debt_auction_bid_size).transact( from_address=self.other_address) assert self.debt_auction_house.bids( auction_id).amount_to_sell == amount_to_sell # when simulate_model_output(model=model, price=Wad.from_number(825.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then auction = self.debt_auction_house.bids(auction_id) assert auction.amount_to_sell != amount_to_sell assert round( auction.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(auction.amount_to_sell), 2) == round(Rad.from_number(825.0), 2) prot_after = self.geb.prot.balance_of(self.keeper_address) assert prot_before == prot_after # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_should_only_tend_if_bid_is_only_slightly_above_tab( self, mcd, c, kick, keeper, keeper_address): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when auction = flipper.bids(kick) bid_price = Wad(auction.tab) + Wad.from_number(0.1) self.simulate_model_bid(mcd, c, model, bid_price) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then auction = flipper.bids(kick) assert auction.bid == auction.tab assert auction.lot == tend_lot # when keeper.check_all_auctions() wait_for_other_threads() # then auction = flipper.bids(kick) assert auction.bid == auction.tab assert auction.lot == tend_lot # cleanup time_travel_by(self.web3, flipper.ttl() + 1) assert flipper.deal(kick).transact()
def test_should_overbid_itself_if_model_has_updated_the_price( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when simulate_model_output(model=model, price=Wad.from_number(100.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert round( Rad(self.debt_auction_house.bids(auction_id).amount_to_sell), 2) == round(self.debt_auction_bid_size / Rad.from_number(100.0), 2) # when simulate_model_output(model=model, price=Wad.from_number(110.0)) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.amount_to_sell_implies_price(auction_id, Wad.from_number(110.0)) # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_should_increase_gas_price_of_pending_transactions_if_model_increases_gas_price( self, mcd, c, kick, keeper): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when bid_price = Wad.from_number(20.0) reserve_dai(mcd, c, self.keeper_address, bid_price * tend_lot * 2) simulate_model_output(model=model, price=bid_price, gas_price=10) # and self.start_ignoring_transactions() # and keeper.check_all_auctions() keeper.check_for_bids() # and simulate_model_output(model=model, price=bid_price, gas_price=15) # and self.end_ignoring_transactions() # and keeper.check_for_bids() wait_for_other_threads() # then assert flipper.bids(kick).bid == Rad(bid_price * tend_lot) assert self.web3.eth.getBlock( 'latest', full_transactions=True).transactions[0].gasPrice == 15 # cleanup time_travel_by(self.web3, flipper.ttl() + 1) assert flipper.deal(kick).transact()
def test_should_replace_pending_transactions_if_model_lowers_bid_and_increases_gas_price( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when simulate_model_output(model=model, price=Wad.from_number(80.0), gas_price=10) # and self.start_ignoring_transactions() # and self.keeper.check_all_auctions() # and time.sleep(2) # and self.end_ignoring_transactions() # and simulate_model_output(model=model, price=Wad.from_number(70.0), gas_price=15) # and self.keeper.check_for_bids() wait_for_other_threads() # then assert self.amount_to_sell_implies_price(auction_id, Wad.from_number(70.0)) assert self.web3.eth.getBlock( 'latest', full_transactions=True).transactions[0].gasPrice == 15 # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_should_not_dent_on_rounding_errors_with_small_amounts( self, mcd, c, keeper): # given flipper = c.flipper kick_small_lot = flipper.kicks() (model, model_factory) = models(keeper, kick_small_lot) # when auction = flipper.bids(kick_small_lot) bid_price = Wad(auction.tab / Rad(tend_small_lot)) self.simulate_model_bid(mcd, c, model, bid_price) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert flipper.bids(kick_small_lot).lot == auction.lot # when tx_count = self.web3.eth.getTransactionCount( self.keeper_address.address) # and keeper.check_all_auctions() keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getTransactionCount( self.keeper_address.address) == tx_count
def test_should_not_bid_on_rounding_errors_with_small_amounts( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when simulate_model_output(model=model, price=Wad.from_number(1400.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.debt_auction_house.bids(auction_id).amount_to_sell == Wad( self.debt_auction_bid_size * self.geb.oracle_relayer.redemption_price() / Rad.from_number(1400.0)) # when tx_count = self.web3.eth.getTransactionCount( self.keeper_address.address) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getTransactionCount( self.keeper_address.address) == tx_count
def test_should_terminate_model_if_auction_is_dealt(self, kick): # given kick = self.flapper.kicks() (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when auction = self.flapper.bids(kick) assert self.flapper.tend(kick, auction.lot, Wad.from_number(40)).transact(from_address=self.other_address) # and time_travel_by(self.web3, self.flapper.ttl() + 1) # and assert self.flapper.deal(kick).transact(from_address=self.other_address) # and self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once()
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_kick( self, c, kick, mcd, keeper): # given (model, model_factory) = models(keeper, kick) # when keeper.check_all_auctions() wait_for_other_threads() initial_bid = c.flipper.bids(kick) # then model_factory.create_model.assert_called_once_with( Parameters(flipper=c.flipper.address, flapper=None, flopper=None, id=kick)) # and status = model.send_status.call_args[0][0] assert status.id == kick assert status.flipper == c.flipper.address assert status.flapper is None assert status.flopper is None assert status.bid == Rad.from_number(0) assert status.lot == initial_bid.lot assert status.tab == initial_bid.tab assert status.beg > Wad.from_number(1) assert status.guy == mcd.cat.address assert status.era > 0 assert status.end < status.era + c.flipper.tau() + 1 assert status.tic == 0 assert status.price == Wad(0)
def test_should_replace_pending_transactions_if_model_lowers_bid_and_increases_gas_price(self, kick): # given (model, model_factory) = models(self.keeper, kick) lot = self.flapper.bids(kick).lot # when simulate_model_output(model=model, price=Wad.from_number(10.0), gas_price=10) # and self.start_ignoring_transactions() # and self.keeper.check_all_auctions() self.keeper.check_for_bids() # and self.end_ignoring_transactions() # and simulate_model_output(model=model, price=Wad.from_number(8.0), gas_price=15) # and self.keeper.check_for_bids() wait_for_other_threads() # then assert self.flapper.bids(kick).bid == Wad(lot) / Wad.from_number(8.0) assert self.web3.eth.getBlock('latest', full_transactions=True).transactions[0].gasPrice == 15 # cleanup time_travel_by(self.web3, self.flapper.ttl() + 1) assert self.flapper.deal(kick).transact()
def test_should_terminate_model_if_auction_expired_due_to_tau( self, c, keeper): # given flipper = c.flipper kick = flipper.kicks() (model, model_factory) = models(keeper, kick) # when keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when time_travel_by(self.web3, flipper.tau() + 1) # and keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once() # cleanup assert flipper.deal(kick).transact()
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_kick(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once_with(Parameters(flipper=None, flapper=self.flapper.address, flopper=None, id=kick)) # and status = model.send_status.call_args[0][0] assert status.id == kick assert status.flipper is None assert status.flapper == self.flapper.address assert status.flopper is None assert status.bid == Wad(0) assert status.lot == self.mcd.vow.bump() assert status.tab is None assert status.beg == Wad.from_number(1.05) assert status.guy == self.mcd.vow.address assert status.era > 0 assert status.end < status.era + self.flapper.tau() + 1 assert status.tic == 0 assert status.price is None
def test_should_take_when_price_appropriate(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when our_price = Ray.from_number(153) self.simulate_model_bid(model, our_price) while True: time_travel_by(self.web3, 1) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() lot = self.clipper.sales(kick).lot (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) # when auction price is unacceptable if auction_price > our_price: # then ensure no action is taken assert self.clipper.sales(kick).lot > Wad(0) assert not needs_redo # when auction price is acceptable else: # then ensure take was called assert self.clipper.sales(kick).lot == Wad(0) break # and ensure the take price was appropriate our_take = self.last_log() assert isinstance(our_take, Clipper.TakeLog) assert our_take.price <= our_price