# Path: pgctl/errors.py
# class LockHeld(PgctlUserMessage):
#     """The pgctl supervision lock is held. This generally indicates subprocesses escaping supervision."""
# 
# Path: pgctl/functions.py
# def bestrelpath(path, relto=None):
#     """Return a relative path only if it's under $PWD (or `relto`)"""
#     if relto is None:
#         from os import getcwd
#         relto = getcwd()
#     from os.path import relpath
#     relpath = relpath(path, relto)
#     if relpath.startswith('.'):
#         return path
#     else:
#         return relpath
# 
# Path: pgctl/functions.py
# class JSONEncoder(json.JSONEncoder):
#     """knows that frozendict is like dict"""
# 
#     def default(self, o):
#         if isinstance(o, frozendict):
#             return dict(o)
#         else:
#             # Let the base class default method raise the TypeError
#             return json.JSONEncoder.default(self, o)
# 
# Path: pgctl/functions.py
# def logger_preexec(log_path):
#     """Pre exec func. for starting the logger process for a service.
# 
#     Before execing the logger service (s6-log), connect stdin to the logging
#     FIFO so that it reads log lines from the service, and connect stdout/stderr
#     to the void since we ignore the logger's console output.
#     (The logger writes actual log output to files in $SERVICE_DIR/logs.)
# 
#     :param log_path: path to the logging FIFO
#     """
#     # Even though this is technically RDONLY, we open
#     # it as RDWR to avoid blocking
#     #
#     # http://bugs.python.org/issue10635
#     log_fifo_reader = os.open(log_path, os.O_RDWR)
#     devnull = os.open(os.devnull, os.O_WRONLY)
# 
#     os.dup2(log_fifo_reader, StreamFileDescriptor.STDIN)
#     os.dup2(devnull, StreamFileDescriptor.STDOUT)
#     os.dup2(devnull, StreamFileDescriptor.STDERR)
# 
#     os.close(log_fifo_reader)
#     os.close(devnull)
# 
# Path: pgctl/functions.py
# def show_runaway_processes(path):
#     from .fuser import fuser
#     processes = ps(fuser(path))
#     if processes:
#         raise LockHeld(
#             '''\
# these runaway processes did not stop:
# {}
# This usually means these processes are buggy.
# Normally pgctl would kill these automatically for you, but you specified the --no-force option.
# Learn more: https://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
# '''.format(processes)
#         )
# 
# Path: pgctl/functions.py
# def supervisor_preexec(log_path):
#     """Pre exec func. for starting a service.
# 
#     Before execing the service, attach the output streams of the supervised
#     process to the logging FIFO so that they will be logged to a file by the
#     service's logger (s6-log). Also, attach the service's stdin to the void
#     since it's running in a supervised context (and shouldn't have any data
#     going to stdin).
# 
#     :param log_path: path to the logging pipe
#     """
#     # Should be WRONLY, but we can't block (see logger_preexec)
#     log_fifo_writer = os.open(log_path, os.O_RDWR)
# 
#     devnull = os.open(os.devnull, os.O_RDONLY)
#     os.dup2(devnull, StreamFileDescriptor.STDIN)
#     os.dup2(log_fifo_writer, StreamFileDescriptor.STDOUT)
#     os.dup2(log_fifo_writer, StreamFileDescriptor.STDERR)
# 
#     os.close(log_fifo_writer)
#     os.close(devnull)
# 
# Path: pgctl/functions.py
# def terminate_processes(pids: typing.Iterable[int], is_stop: bool = True) -> typing.Optional[str]:
#     """forcefully kill processes"""
#     processes = ps(pids)
#     if processes:
#         for pid in pids:
#             try:
#                 os.kill(pid, signal.SIGKILL)
#             except OSError:  # pragma: no cover
#                 # race condition: processes stopped slightly after timeout, before we kill it
#                 pass
# 
#         if is_stop:
#             return '''WARNING: Killing these runaway processes which did not stop:
# {}
# This usually means these processes are buggy.
# Learn more: https://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
# '''.format(processes)
#         else:
#             return '''WARNING: Killing these processes which were still running but escaped supervision:
# {}
# This usually means that s6-supervise was not stopped cleanly (e.g. manually killed).
# Learn more: https://pgctl.readthedocs.io/en/latest/user/usage.html#stop
# '''.format(processes)
# 
# Path: pgctl/functions.py
# def unique(iterable):
#     """remove duplicates while preserving ordering -- first one wins"""
#     return tuple(_unique(iterable))
# 
# Path: pgctl/subprocess.py
# def set_defaults(func, **defaults):
#     def wrapped(cmd, **kwargs):
# PIPE = subprocess.PIPE
# STDOUT = subprocess.STDOUT


import os
import pytest
from unittest import mock
from frozendict import frozendict
from testfixtures import ShouldRaise
from testing.assertions import wait_for
from testing.norm import norm_trailing_whitespace_json
from pgctl.errors import LockHeld
from pgctl.functions import bestrelpath
from pgctl.functions import JSONEncoder
from pgctl.functions import logger_preexec
from pgctl.functions import show_runaway_processes
from pgctl.functions import supervisor_preexec
from pgctl.functions import terminate_processes
from pgctl.functions import unique
from pgctl.subprocess import Popen




class DescribeUnique:

    def it_does_not_have_duplicates(self):
        data = ['b', 'b', 'b']

# Path: pgctl/errors.py
# class LockHeld(PgctlUserMessage):
#     """The pgctl supervision lock is held. This generally indicates subprocesses escaping supervision."""
# 
# Path: pgctl/functions.py
# def bestrelpath(path, relto=None):
#     """Return a relative path only if it's under $PWD (or `relto`)"""
#     if relto is None:
#         from os import getcwd
#         relto = getcwd()
#     from os.path import relpath
#     relpath = relpath(path, relto)
#     if relpath.startswith('.'):
#         return path
#     else:
#         return relpath
# 
# Path: pgctl/functions.py
# class JSONEncoder(json.JSONEncoder):
#     """knows that frozendict is like dict"""
# 
#     def default(self, o):
#         if isinstance(o, frozendict):
#             return dict(o)
#         else:
#             # Let the base class default method raise the TypeError
#             return json.JSONEncoder.default(self, o)
# 
# Path: pgctl/functions.py
# def logger_preexec(log_path):
#     """Pre exec func. for starting the logger process for a service.
# 
#     Before execing the logger service (s6-log), connect stdin to the logging
#     FIFO so that it reads log lines from the service, and connect stdout/stderr
#     to the void since we ignore the logger's console output.
#     (The logger writes actual log output to files in $SERVICE_DIR/logs.)
# 
#     :param log_path: path to the logging FIFO
#     """
#     # Even though this is technically RDONLY, we open
#     # it as RDWR to avoid blocking
#     #
#     # http://bugs.python.org/issue10635
#     log_fifo_reader = os.open(log_path, os.O_RDWR)
#     devnull = os.open(os.devnull, os.O_WRONLY)
# 
#     os.dup2(log_fifo_reader, StreamFileDescriptor.STDIN)
#     os.dup2(devnull, StreamFileDescriptor.STDOUT)
#     os.dup2(devnull, StreamFileDescriptor.STDERR)
# 
#     os.close(log_fifo_reader)
#     os.close(devnull)
# 
# Path: pgctl/functions.py
# def show_runaway_processes(path):
#     from .fuser import fuser
#     processes = ps(fuser(path))
#     if processes:
#         raise LockHeld(
#             '''\
# these runaway processes did not stop:
# {}
# This usually means these processes are buggy.
# Normally pgctl would kill these automatically for you, but you specified the --no-force option.
# Learn more: https://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
# '''.format(processes)
#         )
# 
# Path: pgctl/functions.py
# def supervisor_preexec(log_path):
#     """Pre exec func. for starting a service.
# 
#     Before execing the service, attach the output streams of the supervised
#     process to the logging FIFO so that they will be logged to a file by the
#     service's logger (s6-log). Also, attach the service's stdin to the void
#     since it's running in a supervised context (and shouldn't have any data
#     going to stdin).
# 
#     :param log_path: path to the logging pipe
#     """
#     # Should be WRONLY, but we can't block (see logger_preexec)
#     log_fifo_writer = os.open(log_path, os.O_RDWR)
# 
#     devnull = os.open(os.devnull, os.O_RDONLY)
#     os.dup2(devnull, StreamFileDescriptor.STDIN)
#     os.dup2(log_fifo_writer, StreamFileDescriptor.STDOUT)
#     os.dup2(log_fifo_writer, StreamFileDescriptor.STDERR)
# 
#     os.close(log_fifo_writer)
#     os.close(devnull)
# 
# Path: pgctl/functions.py
# def terminate_processes(pids: typing.Iterable[int], is_stop: bool = True) -> typing.Optional[str]:
#     """forcefully kill processes"""
#     processes = ps(pids)
#     if processes:
#         for pid in pids:
#             try:
#                 os.kill(pid, signal.SIGKILL)
#             except OSError:  # pragma: no cover
#                 # race condition: processes stopped slightly after timeout, before we kill it
#                 pass
# 
#         if is_stop:
#             return '''WARNING: Killing these runaway processes which did not stop:
# {}
# This usually means these processes are buggy.
# Learn more: https://pgctl.readthedocs.org/en/latest/user/quickstart.html#writing-playground-services
# '''.format(processes)
#         else:
#             return '''WARNING: Killing these processes which were still running but escaped supervision:
# {}
# This usually means that s6-supervise was not stopped cleanly (e.g. manually killed).
# Learn more: https://pgctl.readthedocs.io/en/latest/user/usage.html#stop
# '''.format(processes)
# 
# Path: pgctl/functions.py
# def unique(iterable):
#     """remove duplicates while preserving ordering -- first one wins"""
#     return tuple(_unique(iterable))
# 
# Path: pgctl/subprocess.py
# def set_defaults(func, **defaults):
#     def wrapped(cmd, **kwargs):
# PIPE = subprocess.PIPE
# STDOUT = subprocess.STDOUT


# Path: tests/unit/functions.py
import os
import pytest
from unittest import mock
from frozendict import frozendict
from testfixtures import ShouldRaise
from testing.assertions import wait_for
from testing.norm import norm_trailing_whitespace_json
from pgctl.errors import LockHeld
from pgctl.functions import bestrelpath
from pgctl.functions import JSONEncoder
from pgctl.functions import logger_preexec
from pgctl.functions import show_runaway_processes
from pgctl.functions import supervisor_preexec
from pgctl.functions import terminate_processes
from pgctl.functions import unique
from pgctl.subprocess import Popen





class DescribeUnique:

    def it_does_not_have_duplicates(self):
        data = ['b', 'b', 'b']

        assert list(unique(data)) == ['b']