Пример #1
0
def test_market_accept_bid_yields_partial_bid_trade(market: TwoSidedPayAsBid):
    bid = market.bid(2.0, 4, 'buyer', 'seller')
    trade = market.accept_bid(bid,
                              energy=1,
                              seller='seller',
                              trade_offer_info=[2, 2, 1, 1, 2])
    assert trade.offer.id == bid.id and trade.offer.energy == 1
Пример #2
0
def test_market_trade_bid_not_found(market: TwoSidedPayAsBid):
    bid = market.bid(20, 10, 'A', 'B')

    assert market.accept_bid(bid, 10, 'B')

    with pytest.raises(BidNotFound):
        market.accept_bid(bid, 10, 'B')
Пример #3
0
def test_market_accept_bid_always_updates_trade_stats(market: TwoSidedPayAsBid, called,
                                                      market_method):
    setattr(market, market_method, called)

    bid = market.bid(20, 20, 'A', 'B')
    trade = market.accept_bid(bid, energy=5, seller='B', already_tracked=False)
    assert trade
    assert len(getattr(market, market_method).calls) == 1
Пример #4
0
 def setUp(self):
     self.area = Area(name="test_area")
     self.parent_area = Area(name="parent_area")
     self.test_market = TwoSidedPayAsBid(name="test_market")
     self.parent_area._markets.markets = {1: self.test_market}
     self.area.parent = self.parent_area
     self.external_strategy = ExternalStrategy(self.area)
     self.external_redis = self.external_strategy.redis
Пример #5
0
def test_market_trade_partial_bid_invalid(market: TwoSidedPayAsBid, energy):
    bid = market.bid(20, 20, 'A', 'B')

    with pytest.raises(InvalidTrade):
        market.accept_bid(bid,
                          energy=energy,
                          seller='A',
                          trade_offer_info=[1, 1, 1, 1, 1])
Пример #6
0
 def setUp(self):
     ConstSettings.IAASettings.MARKET_TYPE = 1
     self.area = Area(name="test_area")
     self.parent_area = Area(name="parent_area")
     self.test_market = TwoSidedPayAsBid(name="test_market")
     self.parent_area._markets.markets = {1: self.test_market}
     self.area.parent = self.parent_area
     self.external_strategy = ExternalStrategy(self.area)
     self.external_redis = self.external_strategy.redis
Пример #7
0
def test_market_bid_trade(market: TwoSidedPayAsBid):
    bid = market.bid(20, 10, 'A', 'B')

    trade = market.accept_bid(bid, energy=10, seller='B')
    assert trade
    assert trade == market.trades[0]
    assert trade.id
    assert trade.offer is bid
    assert trade.seller == 'B'
    assert trade.buyer == 'A'
    assert not trade.residual
Пример #8
0
def test_market_accept_bid_does_not_emit_bid_deleted_on_partial_bid(market: TwoSidedPayAsBid,
                                                                    called):
    market.add_listener(called)
    bid = market.bid(20, 20, 'A', 'B')
    trade = market.accept_bid(bid, energy=1)
    assert all([ev != repr(MarketEvent.BID_DELETED) for c in called.calls for ev in c[0]])
    assert len(called.calls) == 1
    assert called.calls[0][0] == (repr(MarketEvent.BID_TRADED), )
    assert called.calls[0][1] == {
        'market_id': repr(market.id),
        'bid_trade': repr(trade),
    }
Пример #9
0
def test_market_bid_trade(market: TwoSidedPayAsBid):
    bid = market.bid(20, 10, 'A', 'B', original_bid_price=20)

    trade = market.accept_bid(bid,
                              energy=10,
                              seller='B',
                              trade_offer_info=[2, 2, 0.5, 0.5, 2])
    assert trade
    assert trade.id == market.trades[0].id
    assert trade.id
    assert trade.offer.price == bid.price
    assert trade.offer.energy == bid.energy
    assert trade.seller == 'B'
    assert trade.buyer == 'A'
    assert not trade.residual
Пример #10
0
def test_market_trade_bid_not_found(market=TwoSidedPayAsBid(time_slot=now())):
    bid = market.bid(20, 10, 'A', 'B', 'A')

    assert market.accept_bid(bid, 10, 'B', trade_offer_info=[2, 2, 1, 1, 2])

    with pytest.raises(BidNotFound):
        market.accept_bid(bid, 10, 'B', trade_offer_info=[2, 2, 1, 1, 2])
Пример #11
0
def test_market_accept_bid_emits_bid_traded_and_bid_deleted_event(market: TwoSidedPayAsBid,
                                                                  called):
    market.add_listener(called)
    bid = market.bid(20, 20, 'A', 'B')
    trade = market.accept_bid(bid)
    assert len(called.calls) == 2
    assert called.calls[0][0] == (repr(MarketEvent.BID_TRADED), )
    assert called.calls[1][0] == (repr(MarketEvent.BID_DELETED), )
    assert called.calls[0][1] == {
        'market_id': repr(market.id),
        'bid_trade': repr(trade),
    }
    assert called.calls[1][1] == {
        'market_id': repr(market.id),
        'bid': repr(bid),
    }
Пример #12
0
def test_market_bid(market: TwoSidedPayAsBid):
    bid = market.bid(1, 2, 'bidder', 'seller', 'bidder')
    assert market.bids[bid.id] == bid
    assert bid.price == 1
    assert bid.energy == 2
    assert bid.buyer == 'bidder'
    assert bid.seller == 'seller'
    assert len(bid.id) == 36
Пример #13
0
def test_market_bid_accepts_bid_id(market: TwoSidedPayAsBid):
    bid = market.bid(1, 2, 'bidder', 'seller', 'bidder', bid_id='123')
    assert market.bids['123'] == bid
    assert bid.id == '123'
    assert bid.price == 1
    assert bid.energy == 2
    assert bid.buyer == 'bidder'
    assert bid.seller == 'seller'

    # Update existing bid is tested here
    bid = market.bid(3, 4, 'updated_bidder', 'updated_seller', 'updated_bidder', bid_id='123')
    assert market.bids['123'] == bid
    assert bid.id == '123'
    assert isclose(bid.price, 3)
    assert bid.energy == 4
    assert bid.buyer == 'updated_bidder'
    assert bid.seller == 'updated_seller'
Пример #14
0
def test_market_accept_bid_always_updates_trade_stats(
        called, market_method, market=TwoSidedPayAsBid(time_slot=now())):
    setattr(market, market_method, called)

    bid = market.bid(20, 20, 'A', 'B', 'A')
    trade = market.accept_bid(bid, energy=5, seller='B', trade_offer_info=[1, 1, 1, 1, 1])
    assert trade
    assert len(getattr(market, market_method).calls) == 1
Пример #15
0
def test_market_trade_partial_bid_invalid(
    energy, market=TwoSidedPayAsBid(time_slot=DateTime.now())):
    bid = market.bid(20, 20, 'A', 'B', 'A')

    with pytest.raises(InvalidTrade):
        market.accept_bid(bid,
                          energy=energy,
                          seller='A',
                          trade_offer_info=[1, 1, 1, 1, 1])
Пример #16
0
def test_market_trade_bid_partial(market: TwoSidedPayAsBid):
    bid = market.bid(20, 20, 'A', 'B')

    trade = market.accept_bid(bid, energy=5, seller='B')
    assert trade
    assert trade == market.trades[0]
    assert trade.id
    assert trade.offer is not bid
    assert trade.offer.energy == 5
    assert trade.offer.price == 5
    assert trade.offer.seller == 'B'
    assert trade.seller == 'B'
    assert trade.buyer == 'A'
    assert trade.residual
    assert len(market.bids) == 1
    assert bid.id in market.bids
    assert market.bids[bid.id].energy == 15
    assert market.bids[bid.id].price == 15
    assert market.bids[bid.id].seller == 'B'
    assert market.bids[bid.id].buyer == 'A'
Пример #17
0
def test_market_accept_bid_emits_bid_split_on_partial_bid(
        called, market=TwoSidedPayAsBid(time_slot=now())):
    market.add_listener(called)
    bid = market.bid(20, 20, 'A', 'B', 'A')
    trade = market.accept_bid(bid, energy=1, trade_offer_info=[1, 1, 1, 1, 1])
    assert all([ev != repr(MarketEvent.BID_DELETED) for c in called.calls for ev in c[0]])
    assert len(called.calls) == 2
    assert called.calls[0][0] == (repr(MarketEvent.BID_SPLIT),)
    assert called.calls[1][0] == (repr(MarketEvent.BID_TRADED),)
    assert called.calls[1][1] == {
        'market_id': repr(market.id),
        'bid_trade': repr(trade),
    }
Пример #18
0
def test_market_trade_bid_partial(market: TwoSidedPayAsBid):
    bid = market.bid(20, 20, 'A', 'B', original_bid_price=20)

    trade = market.accept_bid(bid,
                              energy=5,
                              seller='B',
                              trade_offer_info=[1, 1, 1, 1, 1])
    assert trade
    assert trade.id == market.trades[0].id
    assert trade.id
    assert trade.offer is not bid
    assert trade.offer.energy == 5
    assert trade.offer.price == 5
    assert trade.offer.seller == 'B'
    assert trade.seller == 'B'
    assert trade.buyer == 'A'
    assert trade.residual
    assert len(market.bids) == 1
    assert trade.residual.id in market.bids
    assert market.bids[trade.residual.id].energy == 15
    assert isclose(market.bids[trade.residual.id].price, 15)
    assert market.bids[trade.residual.id].seller == 'B'
    assert market.bids[trade.residual.id].buyer == 'A'
Пример #19
0
def test_market_accept_bid_emits_bid_traded_and_bid_deleted_event(
    called, market=TwoSidedPayAsBid(time_slot=DateTime.now())):
    market.add_listener(called)
    bid = market.bid(20, 20, 'A', 'B')
    trade = market.accept_bid(bid, trade_offer_info=[1, 1, 1, 1, 1])
    assert len(called.calls) == 2
    assert called.calls[0][0] == (repr(MarketEvent.BID_TRADED), )
    assert called.calls[1][0] == (repr(MarketEvent.BID_DELETED), )
    assert called.calls[0][1] == {
        'market_id': repr(market.id),
        'bid_trade': repr(trade),
    }
    assert called.calls[1][1] == {
        'market_id': repr(market.id),
        'bid': repr(bid),
    }
Пример #20
0
def market():
    return TwoSidedPayAsBid()
Пример #21
0
    assert bid.buyer == 'updated_bidder'
    assert bid.seller == 'updated_seller'


def test_market_offer_invalid(market: OneSidedMarket):
    with pytest.raises(InvalidOffer):
        market.offer(10, -1, 'someone', 'someone')


def test_market_bid_invalid(market: TwoSidedPayAsBid):
    with pytest.raises(InvalidBid):
        market.bid(10, -1, 'someone', 'noone', 'someone')


@pytest.mark.parametrize("market, offer",
                         [(TwoSidedPayAsBid(), "offer"),
                          (BalancingMarket(), "balancing_offer")])
def test_market_offer_readonly(market, offer):
    market.readonly = True
    with pytest.raises(MarketReadOnlyException):
        getattr(market, offer)(10, 10, 'A', 'A')


@pytest.mark.parametrize(
    "market, offer",
    [(TwoSidedPayAsBid(time_slot=DateTime.now()), "offer"),
     (BalancingMarket(time_slot=DateTime.now()), "balancing_offer")])
def test_market_offer_delete(market, offer):
    offer = getattr(market, offer)(20, 10, 'someone', 'someone')
    market.delete_offer(offer)
Пример #22
0
def market():
    return TwoSidedPayAsBid(time_slot=now())
Пример #23
0
class TestExternalStrategy(unittest.TestCase):
    def setUp(self):
        ConstSettings.IAASettings.MARKET_TYPE = 1
        self.area = Area(name="test_area")
        self.parent_area = Area(name="parent_area")
        self.test_market = TwoSidedPayAsBid(name="test_market",
                                            time_slot=now())
        self.parent_area._markets.markets = {1: self.test_market}
        self.area.parent = self.parent_area
        self.external_strategy = ExternalStrategy(self.area)
        self.external_redis = self.external_strategy.redis

    def tearDown(self):
        ConstSettings.IAASettings.MARKET_TYPE = 1

    @parameterized.expand([(2, ), (3, )])
    def test_sub_to_external_requests_exposes_correct_channels_two_sided_market(
            self, market_type):
        ConstSettings.IAASettings.MARKET_TYPE = market_type
        self.external_strategy2 = ExternalStrategy(self.area)
        self.external_strategy2.redis.redis_db.sub_to_multiple_channels.assert_called_once_with(
            {
                "parent-area/test-area/offer":
                self.external_strategy2.redis._offer,
                "parent-area/test-area/delete_offer":
                self.external_strategy2.redis._delete_offer,
                "parent-area/test-area/delete_bid":
                self.external_strategy2.redis._delete_bid,
                "parent-area/test-area/bid":
                self.external_strategy2.redis._bid,
                "parent-area/test-area/bids":
                self.external_strategy2.redis._list_bids,
                "parent-area/test-area/offers":
                self.external_strategy2.redis._offer_lists
            })

    def test_sub_to_external_requests_exposes_correct_channels_one_sided_market(
            self):
        self.external_redis.redis_db.sub_to_multiple_channels.assert_called_once_with(
            {
                "parent-area/test-area/offer": self.external_redis._offer,
                "parent-area/test-area/delete_offer":
                self.external_redis._delete_offer,
                "parent-area/test-area/accept_offer":
                self.external_redis._accept_offer,
                "parent-area/test-area/offers":
                self.external_redis._offer_lists
            })

    def _assert_dict_is_the_same_as_offer(self, offer_dict, offer):
        assert offer.id == offer_dict["id"]
        assert offer.price == offer_dict["price"]
        assert offer.energy == offer_dict["energy"]

    def test_list_offers(self):
        offer1 = self.test_market.offer(1, 2, "A", "A")
        offer2 = self.test_market.offer(2, 3, "B", "B")
        offer3 = self.test_market.offer(3, 4, "C", "C")
        self.external_redis._offer_lists("")
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/offers/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        offers_dict = response_payload["offer_list"]
        assert len(offers_dict) == 3
        self._assert_dict_is_the_same_as_offer(offers_dict[0], offer1)
        self._assert_dict_is_the_same_as_offer(offers_dict[1], offer2)
        self._assert_dict_is_the_same_as_offer(offers_dict[2], offer3)

    @parameterized.expand([(2, ), (3, )])
    def test_list_offers_two_sided(self, market_type):
        ConstSettings.IAASettings.MARKET_TYPE = market_type
        offer1 = self.test_market.offer(1, 2, "test_area", "test_area")
        offer2 = self.test_market.offer(2, 3, "test_area", "test_area")
        self.test_market.offer(3, 4, "C", "C")
        self.external_redis._offer_lists("")
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/offers/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        offers_dict = response_payload["offer_list"]
        assert len(offers_dict) == 2
        self._assert_dict_is_the_same_as_offer(offers_dict[0], offer1)
        self._assert_dict_is_the_same_as_offer(offers_dict[1], offer2)

    def test_offer(self):
        payload = {"data": json.dumps({"energy": 22, "price": 54})}
        self.external_redis._offer(payload)
        assert len(self.test_market.offers) == 1
        offer = list(self.test_market.offers.values())[0]
        assert offer.price == 54
        assert offer.energy == 22
        assert offer.seller == "test_area"
        market_offer_json = offer.to_JSON_string()
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/offer/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        assert response_payload["offer"] == market_offer_json

    def test_delete_offer(self):
        offer1 = self.test_market.offer(1, 2, "A", "A")
        payload = {"data": json.dumps({"offer": offer1.to_JSON_string()})}
        self.external_redis._delete_offer(payload)
        assert len(self.test_market.offers) == 0
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/delete_offer/response"

    def test_accept_offer(self):
        offer1 = self.test_market.offer(1, 2, "A", "A")
        payload = {"data": json.dumps({"offer": offer1.to_JSON_string()})}
        self.external_redis._accept_offer(payload)
        assert len(self.test_market.trades) == 1
        trade = self.test_market.trades[0]
        assert len(self.test_market.offers) == 0
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/accept_offer/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        assert response_payload["trade"] == trade.to_JSON_string()

    def test_bid(self):
        payload = {"data": json.dumps({"energy": 12, "price": 32})}
        self.external_redis._bid(payload)
        assert len(self.test_market.bids) == 1
        bid = list(self.test_market.bids.values())[0]
        assert bid.price == 32
        assert bid.energy == 12
        assert bid.buyer == "test_area"
        assert bid.seller == "parent_area"
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/bid/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        assert response_payload["bid"] == bid.to_JSON_string()

    def test_delete_bid(self):
        bid1 = self.test_market.bid(1, 2, "B", "C", "B")
        payload = {"data": json.dumps({"bid": bid1.id})}
        self.external_redis._delete_bid(payload)
        assert len(self.test_market.bids) == 0
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/delete_bid/response"

    @parameterized.expand([(2, ), (3, )])
    def test_list_bids(self, market_type):
        ConstSettings.IAASettings.MARKET_TYPE = market_type
        bid1 = self.test_market.bid(1, 2, "test_area", "A", "test_area")
        bid2 = self.test_market.bid(2, 3, "test_area", "B", "test_area")
        bid3 = self.test_market.bid(3, 4, "test_area", "C", "test_area")
        self.external_redis._list_bids("")
        self.external_redis.redis_db.publish.assert_called_once()
        assert self.external_redis.redis_db.publish.call_args_list[0][0][0] == \
            "parent-area/test-area/bids/response"
        response_payload = json.loads(
            self.external_redis.redis_db.publish.call_args_list[0][0][1])
        bids_list = response_payload["bid_list"]
        assert len(bids_list) == 3
        self._assert_dict_is_the_same_as_offer(bids_list[0], bid1)
        self._assert_dict_is_the_same_as_offer(bids_list[1], bid2)
        self._assert_dict_is_the_same_as_offer(bids_list[2], bid3)

    def test_get_channel_list_fetches_correct_channel_names(self):
        channel_list = self.external_strategy.get_channel_list()
        assert set(channel_list["available_publish_channels"]) == {
            "parent-area/test-area/offer",
            "parent-area/test-area/delete_offer",
            "parent-area/test-area/accept_offer",
            "parent-area/test-area/offers"
        }
        assert set(channel_list["available_subscribe_channels"]) == {
            "parent-area/test-area/market_cycle"
        }
Пример #24
0
def test_market_bid_delete_missing(market: TwoSidedPayAsBid):
    with pytest.raises(BidNotFound):
        market.delete_bid("no such offer")
Пример #25
0
def test_market_bid_invalid(market: TwoSidedPayAsBid):
    with pytest.raises(InvalidBid):
        market.bid(10, -1, 'someone', 'noone', 'someone')
Пример #26
0
    assert bid.seller == 'updated_seller'
    assert bid.market == market


def test_market_offer_invalid(market: OneSidedMarket):
    with pytest.raises(InvalidOffer):
        market.offer(10, -1, 'someone')


def test_market_bid_invalid(market: TwoSidedPayAsBid):
    with pytest.raises(InvalidBid):
        market.bid(10, -1, 'someone', 'noone')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(), "offer"),
    (BalancingMarket(), "balancing_offer")
])
def test_market_offer_readonly(market, offer):
    market.readonly = True
    with pytest.raises(MarketReadOnlyException):
        getattr(market, offer)(10, 10, 'A')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(), "offer"),
    (BalancingMarket(), "balancing_offer")
])
def test_market_offer_delete(market, offer):
    offer = getattr(market, offer)(20, 10, 'someone')
    market.delete_offer(offer)
Пример #27
0
def test_market_bid_delete_id(market: TwoSidedPayAsBid):
    bid = market.bid(20, 10, 'someone', 'noone', 'someone')
    assert bid.id in market.bids

    market.delete_bid(bid.id)
    assert bid.id not in market.bids
Пример #28
0
def market():
    return TwoSidedPayAsBid(area=FakeArea("FakeArea"))
Пример #29
0
    assert bid.buyer == 'updated_bidder'
    assert bid.seller == 'updated_seller'


def test_market_offer_invalid(market: OneSidedMarket):
    with pytest.raises(InvalidOffer):
        market.offer(10, -1, 'someone', 'someone')


def test_market_bid_invalid(market: TwoSidedPayAsBid):
    with pytest.raises(InvalidBid):
        market.bid(10, -1, 'someone', 'noone', 'someone')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(), "offer"),
    (BalancingMarket(), "balancing_offer")
])
def test_market_offer_readonly(market, offer):
    market.readonly = True
    with pytest.raises(MarketReadOnlyException):
        getattr(market, offer)(10, 10, 'A', 'A')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(time_slot=now()), "offer"),
    (BalancingMarket(time_slot=now()), "balancing_offer")
])
def test_market_offer_delete(market, offer):
    offer = getattr(market, offer)(20, 10, 'someone', 'someone')
    market.delete_offer(offer)
Пример #30
0
    assert bid.buyer == 'updated_bidder'
    assert bid.seller == 'updated_seller'


def test_market_offer_invalid(market: OneSidedMarket):
    with pytest.raises(InvalidOffer):
        market.offer(10, -1, 'someone')


def test_market_bid_invalid(market: TwoSidedPayAsBid):
    with pytest.raises(InvalidBid):
        market.bid(10, -1, 'someone', 'noone')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(area=FakeArea("FakeArea", transfer_fee_pct=0)), "offer"),
    (BalancingMarket(area=FakeArea("FakeArea", transfer_fee_pct=0)),
     "balancing_offer")
])
def test_market_offer_readonly(market, offer):
    market.readonly = True
    with pytest.raises(MarketReadOnlyException):
        getattr(market, offer)(10, 10, 'A')


@pytest.mark.parametrize("market, offer", [
    (TwoSidedPayAsBid(area=FakeArea("FakeArea", transfer_fee_pct=0)), "offer"),
    (BalancingMarket(area=FakeArea("FakeArea", transfer_fee_pct=0)),
     "balancing_offer")
])
def test_market_offer_delete(market, offer):