# Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Testing utilities for ``flocker.node``.
"""

from unittest import skipUnless
from subprocess import Popen

from ..testtools import loop_until


def docker_running():
    """
    :return: ``True`` if Docker is installed and running, else ``False``.

    XXX This is terrible (https://clusterhq.atlassian.net/browse/FLOC-85)
    """
    try:
        return not Popen([b"docker", b"version"]).wait()
    except OSError as e:
        if e.args == (2, 'No such file or directory'):
            return False

if_docker_configured = skipUnless(docker_running(),
                                  "Docker must be installed and running.")


def wait_for_unit_state(docker_client, unit_name, expected_activation_states):
    """
    Wait until a unit is in the requested state.

    :param docker_client: A ``DockerClient`` instance.
    :param unicode unit_name: The name of the unit.
    :param expected_activation_states: Activation states to wait for.

    :return: ``Deferred`` that fires when required state has been reached.
    """
    def is_in_states(units):
        for unit in units:
            if unit.name == unit_name:
                if unit.activation_state in expected_activation_states:
                    return True

    def check_if_in_states():
        responded = docker_client.list()
        responded.addCallback(is_in_states)
        return responded

    return loop_until(check_if_in_states)

@@ -104,16 +104,53 @@
 %60.%0A%22%22%22%0A%0A
+import errno%0Aimport os%0Aimport socket%0A
 from uni
@@ -177,37 +177,49 @@
 ess%0A
+%0A
 from 
-subprocess import Popen%0A
+._docker import BASE_DOCKER_API_URL
 %0Afro
@@ -251,16 +251,67 @@
 _until%0A%0A
+SOCKET_PATH = BASE_DOCKER_API_URL.split(':/')%5B-1%5D%0A%0A
 %0Adef doc
@@ -314,23 +314,26 @@
  docker_
-running
+accessible
 ():%0A    
@@ -344,105 +344,79 @@
     
-:return: %60%60True%60%60 if Docker is installed and running, else %60%60False%60%60
+Attempt to connect to the Docker control socket
 .%0A%0A    
-XXX 
 This 
-is terrible (
+may address 
 http
@@ -461,82 +461,185 @@
 C-85
-)%0A    %22%22%22%0A    try:%0A        return not Popen(%5Bb%22docker%22, b%22version%22%5D).wait(
+.%0A%0A    :return: %60%60True%60%60 if the current user has permission to connect, else%0A        %60%60False%60%60.%0A    %22%22%22%0A    try:%0A        socket.socket(family=socket.AF_UNIX).connect(SOCKET_PATH
 )%0A  
@@ -651,11 +651,16 @@
 ept 
-OSE
+socket.e
 rror
@@ -683,73 +683,159 @@
 f e.
-args == (2, 'No such file or directory'):%0A            return Fals
+errno == errno.EACCES:%0A            return False%0A        if e.errno == errno.ENOENT:%0A            return False%0A        raise%0A    else:%0A        return Tru
 e%0A%0Ai
@@ -871,30 +871,38 @@
 ess(
+%0A    
 docker_
-running
+accessible
 (),%0A    
     
@@ -901,77 +901,130 @@
     
- 
-                             %22Docker must be installed and running.%22
+%22User '%7B%7D' does not have permission %22%0A    %22to access the Docker server socket '%7B%7D'%22.format(os.getlogin(),%0A    SOCKET_PATH)
 )%0A%0A%0A

Use existing code to test if docker is accessible