import pytest
from plenum.common.messages.node_messages import NewView
from plenum.test.helper import sdk_send_random_and_check, waitForViewChange
from plenum.test.node_catchup.helper import ensure_all_nodes_have_same_data
from plenum.test.node_request.helper import sdk_ensure_pool_functional

call_count = 0


@pytest.fixture(scope='function', params=range(1, 3))
def lost_count(request):
    return request.param


def test_view_change_with_lost_new_view(txnPoolNodeSet,
                                         looper,
                                         sdk_pool_handle,
                                         sdk_wallet_steward,
                                         tconf,
                                         tdir,
                                         allPluginsPath,
                                         monkeypatch,
                                         lost_count):
    '''
    Skip processing of lost_count Message Responses with NewView
    in view change; test makes sure that the node eventually finishes view change
    '''

    node_to_disconnect = txnPoolNodeSet[-1]
    initial_view_no = txnPoolNodeSet[0].viewNo

    sdk_send_random_and_check(looper, txnPoolNodeSet,
                              sdk_pool_handle, sdk_wallet_steward, 5)

    def unpatch_after_call(msg, frm):
        global call_count
        call_count += 1

        if call_count >= lost_count:
            # unpatch sendToReplica for NewView after lost_count calls
            node_to_disconnect.nodeMsgRouter.add((NewView, node_to_disconnect.sendToReplica))
            call_count = 0

    # patch sendToReplica for routing NewView
    node_to_disconnect.nodeMsgRouter.add((NewView, unpatch_after_call))

    # trigger view change on all nodes
    for n in txnPoolNodeSet:
        n.view_changer.on_master_degradation()
    waitForViewChange(looper, txnPoolNodeSet, expectedViewNo=initial_view_no + 1)
    ensure_all_nodes_have_same_data(looper, nodes=txnPoolNodeSet)

    # make sure that the pool is functional
    sdk_ensure_pool_functional(looper, txnPoolNodeSet, sdk_wallet_steward, sdk_pool_handle)

@@ -7,16 +7,71 @@
  pytest%0A
+from plenum.test.test_node import ensureElectionsDone%0A%0A
 from ple
@@ -360,16 +360,198 @@
 t = 0%0A%0A%0A
+@pytest.fixture(scope=%22module%22)%0Adef tconf(tconf):%0A    old_timeout = tconf.NEW_VIEW_TIMEOUT%0A    tconf.NEW_VIEW_TIMEOUT = 7%0A    yield tconf%0A%0A    tconf.NEW_VIEW_TIMEOUT = old_timeout%0A%0A%0A
 @pytest.
@@ -596,9 +596,9 @@
 (1, 
-3
+5
 ))%0Ad
@@ -696,33 +696,32 @@
 txnPoolNodeSet,%0A
- 
                 
@@ -784,33 +784,32 @@
                 
- 
 sdk_pool_handle,
@@ -809,17 +809,16 @@
 handle,%0A
- 
         
@@ -913,17 +913,15 @@
     
- 
 tconf,%0A
- 
     
@@ -966,120 +966,8 @@
 ir,%0A
-                                         allPluginsPath,%0A                                         monkeypatch,%0A 
     
@@ -2031,16 +2031,158 @@
 no + 1)%0A
+    ensureElectionsDone(looper=looper, nodes=txnPoolNodeSet,%0A                        customTimeout=tconf.NEW_VIEW_TIMEOUT * (call_count + 1))%0A
     ensu

update test_view_change_with_lost_new_view