if term.squeeze():
            trajectories.append([])

import os
import numpy as np
import torch
import pdb

from trajectory.utils import discretization
from trajectory.utils.arrays import to_torch

from .d4rl import load_environment, qlearning_dataset_with_timeouts
from .preprocessing import dataset_preprocess_functions

def segment(observations, terminals, max_path_length):
    """
        segment `observations` into trajectories according to `terminals`
    """
    assert len(observations) == len(terminals)
    observation_dim = observations.shape[1]

    trajectories = [[]]
    for obs, term in zip(observations, terminals):
        trajectories[-1].append(obs)

    if len(trajectories[-1]) == 0:
        trajectories = trajectories[:-1]

    ## list of arrays because trajectories lengths will be different
    trajectories = [np.stack(traj, axis=0) for traj in trajectories]

    n_trajectories = len(trajectories)
    path_lengths = [len(traj) for traj in trajectories]

    ## pad trajectories to be of equal length
    trajectories_pad = np.zeros((n_trajectories, max_path_length, observation_dim), dtype=trajectories[0].dtype)
    early_termination = np.zeros((n_trajectories, max_path_length), dtype=np.bool)
    for i, traj in enumerate(trajectories):
        path_length = path_lengths[i]
        trajectories_pad[i,:path_length] = traj
        early_termination[i,path_length:] = 1

    return trajectories_pad, early_termination, path_lengths

class SequenceDataset(torch.utils.data.Dataset):

    def __init__(self, env, sequence_length=250, step=10, discount=0.99, max_path_length=1000, penalty=None, device='cuda:0'):
        print(f'[ datasets/sequence ] Sequence length: {sequence_length} | Step: {step} | Max path length: {max_path_length}')
        self.env = env = load_environment(env) if type(env) is str else env
        self.sequence_length = sequence_length
        self.step = step
        self.max_path_length = max_path_length
        self.device = device

        print(f'[ datasets/sequence ] Loading...', end=' ', flush=True)
        dataset = qlearning_dataset_with_timeouts(env.unwrapped, terminate_on_end=True)
        print('✓')

        preprocess_fn = dataset_preprocess_functions.get(env.name)
        if preprocess_fn:
            print(f'[ datasets/sequence ] Modifying environment')
            dataset = preprocess_fn(dataset)

        observations = dataset['observations']
        actions = dataset['actions']
        next_observations = dataset['next_observations']
        rewards = dataset['rewards']
        terminals = dataset['terminals']
        realterminals = dataset['realterminals']

        self.observations_raw = observations
        self.actions_raw = actions
        self.next_observations_raw = next_observations
        self.joined_raw = np.concatenate([observations, actions], axis=-1)
        self.rewards_raw = rewards
        self.terminals_raw = terminals

        ## terminal penalty
        if penalty is not None:
            terminal_mask = realterminals.squeeze()
            self.rewards_raw[terminal_mask] = penalty

        print(f'[ datasets/sequence ] Segmenting...', end=' ', flush=True)
        self.joined_segmented, self.termination_flags, self.path_lengths = segment(self.joined_raw, terminals, max_path_length)
        self.rewards_segmented, *_ = segment(self.rewards_raw, terminals, max_path_length)
        print('✓')

        self.discount = discount
        self.discounts = (discount ** np.arange(self.max_path_length))[:,None]

        ## [ n_paths x max_path_length x 1 ]
        self.values_segmented = np.zeros(self.rewards_segmented.shape)

        for t in range(max_path_length):
            V = (self.rewards_segmented[:,t+1:] * self.discounts[:-t-1]).sum(axis=1)
            self.values_segmented[:,t] = V

        ## add (r, V) to `joined`
        values_raw = self.values_segmented.squeeze(axis=-1).reshape(-1)
        values_mask = ~self.termination_flags.reshape(-1)
        self.values_raw = values_raw[values_mask, None]
        self.joined_raw = np.concatenate([self.joined_raw, self.rewards_raw, self.values_raw], axis=-1)
        self.joined_segmented = np.concatenate([self.joined_segmented, self.rewards_segmented, self.values_segmented], axis=-1)

        ## get valid indices
        indices = []
        for path_ind, length in enumerate(self.path_lengths):
            end = length - 1
            for i in range(end):
                indices.append((path_ind, i, i+sequence_length))

        self.indices = np.array(indices)
        self.observation_dim = observations.shape[1]
        self.action_dim = actions.shape[1]
        self.joined_dim = self.joined_raw.shape[1]

        ## pad trajectories
        n_trajectories, _, joined_dim = self.joined_segmented.shape
        self.joined_segmented = np.concatenate([
            self.joined_segmented,
            np.zeros((n_trajectories, sequence_length-1, joined_dim)),
        ], axis=1)
        self.termination_flags = np.concatenate([
            self.termination_flags,
            np.ones((n_trajectories, sequence_length-1), dtype=np.bool),
        ], axis=1)

    def __len__(self):
        return len(self.indices)

class DiscretizedDataset(SequenceDataset):

    def __init__(self, *args, N=50, discretizer='QuantileDiscretizer', **kwargs):
        super().__init__(*args, **kwargs)
        self.N = N
        discretizer_class = getattr(discretization, discretizer)
        self.discretizer = discretizer_class(self.joined_raw, N)

    def __getitem__(self, idx):
        path_ind, start_ind, end_ind = self.indices[idx]
        path_length = self.path_lengths[path_ind]

        joined = self.joined_segmented[path_ind, start_ind:end_ind:self.step]
        terminations = self.termination_flags[path_ind, start_ind:end_ind:self.step]

        joined_discrete = self.discretizer.discretize(joined)

        ## replace with termination token if the sequence has ended
        assert (joined[terminations] == 0).all(), \
                f'Everything after termination should be 0: {path_ind} | {start_ind} | {end_ind}'
        joined_discrete[terminations] = self.N

        joined_discrete = to_torch(joined_discrete, device='cpu', dtype=torch.long).contiguous()

        ## don't compute loss for parts of the prediction that extend
        ## beyond the max path length
        traj_inds = torch.arange(start_ind, end_ind, self.step)
        mask = torch.ones(joined_discrete.shape, dtype=torch.bool)
        mask[traj_inds > self.max_path_length - self.step] = 0

        ## flatten everything
        joined_discrete = joined_discrete.view(-1)
        mask = mask.view(-1)

        X = joined_discrete[:-1]
        Y = joined_discrete[1:]
        mask = mask[:-1]

        return X, Y, mask

class GoalDataset(DiscretizedDataset):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        pdb.set_trace()

    def __getitem__(self, idx):
        X, Y, mask = super().__getitem__(idx)

        ## get path length for looking up the last transition in the trajcetory
        path_ind, start_ind, end_ind = self.indices[idx]
        path_length = self.path_lengths[path_ind]

        ## the goal is the first `observation_dim` dimensions of the last transition
        goal = self.joined_segmented[path_ind, path_length-1, :self.observation_dim]
        goal_discrete = self.discretizer.discretize(goal, subslice=(0, self.observation_dim))
        goal_discrete = to_torch(goal_discrete, device='cpu', dtype=torch.long).contiguous().view(-1)

        return X, goal_discrete, Y, mask


for obs, term in zip(observations, terminals):
        trajectories[-1].append(obs)
        if term.squeeze():
            trajectories.append([])

import os
import numpy as np
import torch
import pdb

from trajectory.utils import discretization
from trajectory.utils.arrays import to_torch

from .d4rl import load_environment, qlearning_dataset_with_timeouts
from .preprocessing import dataset_preprocess_functions

def segment(observations, terminals, max_path_length):
    """
        segment `observations` into trajectories according to `terminals`
    """
    assert len(observations) == len(terminals)
    observation_dim = observations.shape[1]

    trajectories = [[]]


import os
import numpy as np
import torch
import pdb

from trajectory.utils import discretization
from trajectory.utils.arrays import to_torch

from .d4rl import load_environment, qlearning_dataset_with_timeouts
from .preprocessing import dataset_preprocess_functions

def segment(observations, terminals, max_path_length):
    """
        segment `observations` into trajectories according to `terminals`
    """
    assert len(observations) == len(terminals)
    observation_dim = observations.shape[1]

    tr

ajectories = [[]]
    for obs, term in zip(observations, terminals):
        trajectories[-1].append(obs)
        if term.squeeze():
            trajectories.append([])

    if len(trajectories[-1]) == 0:
        trajectories = trajectories[:-1]

    ## list of arrays because trajectories lengths will be different
    trajectories = [np.stack(traj, axis=0) for traj in trajectories]

    n_trajectories = len(trajectories)
    path_lengths = [len(traj) for traj in trajectories]

    ## pad trajectories to be of equal length
    trajectories_pad = np.zeros((n_trajectories, max_path_length, observation_dim), dtype=trajectories[0].dtype)
    early_termination = np.zeros((n_trajectories, max_path_length), dtype=np.bool)
    for i, traj in enumerate(trajectories):
        path_length = path_lengths[i]
        trajectories_pad[i,:path_length] = traj
        early_termination[i,path_length:] = 1

    return trajectories_pad, early_termination, path_lengths

class SequenceDataset(torch.utils.data.Dataset):

    def __init__(self, env, sequence_length=250, step=10, discount=0.99, max_path_length=1000, penalty=None, device='cuda:0'):
        print(f'[ datasets/sequence ] Sequence length: {sequence_length} | Step: {step} | Max path length: {max_path_length}')
        self.env = env = load_environment(env) if type(env) is str else env
        self.sequence_length = sequence_length
        self.step = step
        self.max_path_length = max_path_length
        self.device = device

        print(f'[ datasets/sequence ] Loading...', end=' ', flush=True)
        dataset = qlearning_dataset_with_timeouts(env.unwrapped, terminate_on_end=True)
        print('✓')

        preprocess_fn = dataset_preprocess_functions.get(env.name)
        if preprocess_fn:
            print(f'[ datasets/sequence ] Modifying environment')
            dataset = preprocess_fn(dataset)

        observations = dataset['observations']
        actions = dataset['actions']
        next_observations = dataset['next_observations']
        rewards = dataset['rewards']
        terminals = dataset['terminals']
        realterminals = dataset['realterminals']

        self.observations_raw = observations
        self.actions_raw = actions
        self.next_observations_raw = next_observations
        self.joined_raw = np.concatenate([observations, actions], axis=-1)
        self.rewards_raw = rewards
        self.terminals_raw = terminals

        ## terminal penalty
        if penalty is not None:
            terminal_mask = realterminals.squeeze()
            self.rewards_raw[terminal_mask] = penalty

        print(f'[ datasets/sequence ] Segmenting...', end=' ', flush=True)
        self.joined_segmented, self.termination_flags, self.path_lengths = segment(self.joined_raw, terminals, max_path_length)
        self.rewards_segmented, *_ = segment(self.rewards_raw, terminals, max_path_length)
        print('✓')

        self.discount = discount
        self.discounts = (discount ** np.arange(self.max_path_length))[:,None]

        ## [ n_paths x max_path_length x 1 ]
        self.values_segmented = np.zeros(self.rewards_segmented.shape)

        for t in range(max_path_length):
            V = (self.rewards_segmented[:,t+1:] * self.discounts[:-t-1]).sum(axis=1)
            self.values_segmented[:,t] = V

        ## add (r, V) to `joined`
        values_raw = self.values_segmented.squeeze(axis=-1).reshape(-1)
        values_mask = ~self.termination_flags.reshape(-1)
        self.values_raw = values_raw[values_mask, None]
        self.joined_raw = np.concatenate([self.joined_raw, self.rewards_raw, self.values_raw], axis=-1)
        self.joined_segmented = np.concatenate([self.joined_segmented, self.rewards_segmented, self.values_segmented], axis=-1)

        ## get valid indices
        indices = []
        for path_ind, length in enumerate(self.path_lengths):
            end = length - 1
            for i in range(end):
                indices.append((path_ind, i, i+sequence_length))

        self.indices = np.array(indices)
        self.observation_dim = observations.shape[1]
        self.action_dim = actions.shape[1]
        self.joined_dim = self.joined_raw.shape[1]

        ## pad trajectories
        n_trajectories, _, joined_dim = self.joined_segmented.shape
        self.joined_segmented = np.concatenate([
            self.joined_segmented,
            np.zeros((n_trajectories, sequence_length-1, joined_dim)),
        ], axis=1)
        self.termination_flags = np.concatenate([
            self.termination_flags,
            np.ones((n_trajectories, sequence_length-1), dtype=np.bool),
        ], axis=1)

    def __len__(self):
        return len(self.indices)

class DiscretizedDataset(SequenceDataset):

    def __init__(self, *args, N=50, discretizer='QuantileDiscretizer', **kwargs):
        super().__init__(*args, **kwargs)
        self.N = N
        discretizer_class = getattr(discretization, discretizer)
        self.discretizer = discretizer_class(self.joined_raw, N)

    def __getitem__(self, idx):
        path_ind, start_ind, end_ind = self.indices[idx]
        path_length = self.path_lengths[path_ind]

        joined = self.joined_segmented[path_ind, start_ind:end_ind:self.step]
        terminations = self.termination_flags[path_ind, start_ind:end_ind:self.step]

        joined_discrete = self.discretizer.discretize(joined)

        ## replace with termination token if the sequence has ended
        assert (joined[terminations] == 0).all(), \
                f'Everything after termination should be 0: {path_ind} | {start_ind} | {end_ind}'
        joined_discrete[terminations] = self.N

        joined_discrete = to_torch(joined_discrete, device='cpu', dtype=torch.long).contiguous()

        ## don't compute loss for parts of the prediction that extend
        ## beyond the max path length
        traj_inds = torch.arange(start_ind, end_ind, self.step)
        mask = torch.ones(joined_discrete.shape, dtype=torch.bool)
        mask[traj_inds > self.max_path_length - self.step] = 0

        ## flatten everything
        joined_discrete = joined_discrete.view(-1)
        mask = mask.view(-1)

        X = joined_discrete[:-1]
        Y = joined_discrete[1:]
        mask = mask[:-1]

        return X, Y, mask

class GoalDataset(DiscretizedDataset):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        pdb.set_trace()

    def __getitem__(self, idx):
        X, Y, mask = super().__getitem__(idx)

        ## get path length for looking up the last transition in the trajcetory
        path_ind, start_ind, end_ind = self.indices[idx]
        path_length = self.path_lengths[path_ind]

        ## the goal is the first `observation_dim` dimensions of the last transition
        goal = self.joined_segmented[path_ind, path_length-1, :self.observation_dim]
        goal_discrete = self.discretizer.discretize(goal, subslice=(0, self.observation_dim))
        goal_discrete = to_torch(goal_discrete, device='cpu', dtype=torch.long).contiguous().view(-1)

        return X, goal_discrete, Y, mask


def __init__(self, modem, on_done=None):

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """

"""Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.
        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.
        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN


"""Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.
        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.
        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN


"""See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):

        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.
        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN


# OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.

        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN


if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.
        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.


# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = mod


        super().__init__(on_done)

        self.modem = modem

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """


if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the modem database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.
        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.
        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):

            return Msg.FINISHED

        return Msg.UNKNOWN


# Modem factory reset handler.
from .. import log
from .. import message as Msg
from .Base import Base

LOG = log.get_logger()

class ModemReset(Base):
    """Modem being factory reset handler.

    This handles a factory reset command being sent to the modem and the
    physically triggering a factory reset on the modem with the set button.

    When this happens, we'll clear the modem all link database.
    """
    def __init__(self, modem, on_done=None):
        """Constructor

        Args
          modem (Modem):  The Insteon modem object.
          on_done: The finished callback.  Calling signature:
                   on_done( bool success, str message, data )
        """
        super().__init__(on_done)

        self.modem = modem

    def msg_received(self, protocol, msg):
        """See if we can handle the message.

        If we get an ACK of the user reset, we'll clear the mode

m database.

        Args:
          protocol  (Protocol):  The Insteon Protocol object
          msg:  Insteon message object that was read.

        Returns:
          Msg.UNKNOWN if we can't handle this message.
          Msg.CONTINUE if we handled the message and expect more.
          Msg.FINISHED if we handled the message and are done.
        """
        # InpUserReset is sent when the user triggers a factory reset
        #     on the physical modem.
        # OutResetModem is sent when we send that command to the modem
        #     to reset it and we'll get an ack/nak back.
        if isinstance(msg, (Msg.OutResetModem, Msg.InpUserReset)):
            if msg.is_ack:
                LOG.warning("Modem has been factory reset")

                # Erase the local modem database.  This also erases the
                # on-disk store of the database.
                self.modem.db.clear()
                self.on_done(True, "Modem has been reset", None)
            else:
                LOG.error("Modem factory reset failed")
                self.on_done(False, "Modem reset failed", None)

            return Msg.FINISHED

        return Msg.UNKNOWN


import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

"""
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


"""
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


"""
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):

        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"


import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)


import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.

        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


if key not in self._snapshot:
                del os.environ[key]

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)


for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)


import pickle
import os

from tests.mocker import MockerTestCase

from smart import sysconf
from smart.sysconfig import SysConfig
from smart.plugins import landscape

CLIENT_CONF = """
[client]
http_proxy = http://proxy.url
https_proxy = https://proxy.url
ftp_proxy = ftp://proxy.url
no_proxy = localdomain
"""

EMPTY_CLIENT_CONF = """
[client]
"""

class EnvironSnapshot(object):

    def __init__(self):
        self._snapshot = os.environ.copy()

    def restore(self):
        os.environ.update(self._snapshot)
        for key in list(os.environ):
            if key not in self._snapshot:
                del os.environ[key]

class LandscapePluginTest(MockerTestCase):

    def setUp(self):
        self.sysconf_state = pickle.dumps(sysconf.object)
        sysconf.object = SysConfig()

        self.original_client_conf_path = landscape.CLIENT_CONF_PATH
        self.client_conf_path = self.makeFile(CLIENT_CONF)
        landscape.CLIENT_CONF_PATH = self.client_conf_path

    def tearDown(self):
        sysconf.object = pickle.loads(self.sysconf_state)
        landscape.CLIENT_CONF_PATH = self.original_client_conf_path

    def write_client_conf(self, content):
        file = open(self.client_conf_path, "w")
        file.write(content)
        file.close()

    def test_default_landscape_config_file_path(self):
        self.assertEquals(self.original_client_conf_path,
                          "/etc/landscape/client.conf")

    def test_nothing_happens_if_not_explicitly_enabled(self):
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_use_proxies_set_in_landscape(self):
        """
        If enabled, the landscape smart plugin will read the proxies
        set in Landscape.
        """
        sysco

nf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy"), "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp://proxy.url")

    def test_also_sets_no_proxy_config(self):
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("no-proxy"), "localdomain")

    def test_plguin_sets_proxies_as_weak(self):
        """
        Settings are weak in the sysconf, which means that settings
        performed explicitly will have precedence.
        """
        sysconf.set("http-proxy", "http-url")
        sysconf.set("https-proxy", "https-url")
        sysconf.set("ftp-proxy", "ftp-url")

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

        self.assertEquals(sysconf.get("http-proxy", weak=True),
                          "http://proxy.url")
        self.assertEquals(sysconf.get("https-proxy", weak=True),
                          "https://proxy.url")
        self.assertEquals(sysconf.get("ftp-proxy", weak=True),
                          "ftp://proxy.url")

    def test_nothing_happens_if_there_are_no_proxy_settings(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_nothing_happens_if_there_is_no_section(self):
        """
        The default settings won't be touched if there are no
        proxy options in the client configuration.
        """
        self.write_client_conf("")
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_when_missing_do_not_override_existing_options(self):
        """
        If there are existing settings, they won't be overriden if
        the Landscape client didn't provide any options.
        """
        sysconf.set("http-proxy", "http-url", weak=True)
        sysconf.set("https-proxy", "https-url", weak=True)
        sysconf.set("ftp-proxy", "ftp-url", weak=True)

        self.write_client_conf(EMPTY_CLIENT_CONF)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), "http-url")
        self.assertEquals(sysconf.get("https-proxy"), "https-url")
        self.assertEquals(sysconf.get("ftp-proxy"), "ftp-url")

    def test_doesnt_break_on_unexisting_file(self):
        os.unlink(self.client_conf_path)
        sysconf.set("use-landscape-proxies", True)
        landscape.run()
        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)

    def test_do_not_override_environment_variable(self):
        """
        If the environment variable is set for some variable, do not
        import the setting from Landscape.
        """
        environ_snapshot = EnvironSnapshot()
        self.addCleanup(environ_snapshot.restore)

        os.environ["http_proxy"] = "http_from_environ"
        os.environ["https_proxy"] = "https_from_environ"
        os.environ["ftp_proxy"] = "ftp_from_environ"

        sysconf.set("use-landscape-proxies", True)
        landscape.run()

        self.assertEquals(sysconf.get("http-proxy"), None)
        self.assertEquals(sysconf.get("https-proxy"), None)
        self.assertEquals(sysconf.get("ftp-proxy"), None)