# Path: bts_tools/monitor.py
# class StableStateMonitor(object):
#     """Monitor a sequence of states, and is able to compute a "stable" state value when N
#     consecutive same states have happened.
#     For example, we only want to decide the client is offline after 3 consecutive 'offline' states
#     to absorb transient errors and avoid reacting too fast on wrong alerts.
#     """
#     def __init__(self, n):
#         self.n = n
#         self.states = deque(maxlen=n+1)
#         self.last_stable_state = None
# 
#     def push(self, state):
#         stable_state = self.stable_state()
#         if stable_state is not None:
#             self.last_stable_state = stable_state
#         self.states.append(state)
# 
#     def stable_state(self):
#         size = len(self.states)
#         if size < self.n:
#             return None
#         last_state = self.states[-1]
#         if all(state == last_state for state in islice(self.states, size-self.n, size)):
#             return last_state
#         return None
# 
#     def just_changed(self):
#         stable_state = self.stable_state()
#         if stable_state is None or self.last_stable_state is None:
#             return False
#         return stable_state != self.last_stable_state


from bts_tools.monitor import StableStateMonitor
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


def test_stable_state_monitor():
    s = StableStateMonitor(3)

    # check initial conditions
    s.push('online')
    assert s.stable_state() == None
    assert s.just_changed() == False
    s.push('online')
    s.push('online')
    assert s.stable_state() == 'online'
    assert s.just_changed() == False

    # simulate transient state
    s.push('offline')
    assert s.stable_state() == None
    assert s.just_changed() == False

# Path: bts_tools/monitor.py
# class StableStateMonitor(object):
#     """Monitor a sequence of states, and is able to compute a "stable" state value when N
#     consecutive same states have happened.
#     For example, we only want to decide the client is offline after 3 consecutive 'offline' states
#     to absorb transient errors and avoid reacting too fast on wrong alerts.
#     """
#     def __init__(self, n):
#         self.n = n
#         self.states = deque(maxlen=n+1)
#         self.last_stable_state = None
# 
#     def push(self, state):
#         stable_state = self.stable_state()
#         if stable_state is not None:
#             self.last_stable_state = stable_state
#         self.states.append(state)
# 
#     def stable_state(self):
#         size = len(self.states)
#         if size < self.n:
#             return None
#         last_state = self.states[-1]
#         if all(state == last_state for state in islice(self.states, size-self.n, size)):
#             return last_state
#         return None
# 
#     def just_changed(self):
#         stable_state = self.stable_state()
#         if stable_state is None or self.last_stable_state is None:
#             return False
#         return stable_state != self.last_stable_state


# Path: tests/test_all.py
from bts_tools.monitor import StableStateMonitor

# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


def test_stable_state_monitor():
    s = StableStateMonitor(3)

    # check initial conditions
    s.push('online')
    assert s.stable_state() == None
    assert s.just_changed() == False
    s.push('online')
    s.push('online')
    assert s.stable_state() == 'online'
    assert s.just_changed() == False

    # simulate transient state
    s.push('offline')
    assert s.stable_state() == None
    assert s.just_changed() == False

    s.push('online')