Revision c346d0ac

b/lib/cmdlib/test.py
37 37
  GetWantedInstances
38 38

  
39 39

  
40
class TestSocketWrapper(object):
41
  """ Utility class that opens a domain socket and cleans up as needed.
42

  
43
  """
44
  def __init__(self):
45
    """ Constructor cleaning up variables to be used.
46

  
47
    """
48
    self.tmpdir = None
49
    self.sock = None
50

  
51
  def Create(self, max_connections=1):
52
    """ Creates a bound and ready socket, cleaning up in case of failure.
53

  
54
    @type max_connections: int
55
    @param max_connections: The number of max connections allowed for the
56
                            socket.
57

  
58
    @rtype: tuple of socket, string
59
    @return: The socket object and the path to reach it with.
60

  
61
    """
62
    # Using a temporary directory as there's no easy way to create temporary
63
    # sockets without writing a custom loop around tempfile.mktemp and
64
    # socket.bind
65
    self.tmpdir = tempfile.mkdtemp()
66
    try:
67
      tmpsock = utils.PathJoin(self.tmpdir, "sock")
68
      logging.debug("Creating temporary socket at %s", tmpsock)
69
      self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
70
      try:
71
        self.sock.bind(tmpsock)
72
        self.sock.listen(max_connections)
73
      except:
74
        self.sock.close()
75
        raise
76
    except:
77
      shutil.rmtree(self.tmpdir)
78
      raise
79

  
80
    return self.sock, tmpsock
81

  
82
  def Destroy(self):
83
    """ Destroys the socket and performs all necessary cleanup.
84

  
85
    """
86
    if self.tmpdir is None or self.sock is None:
87
      raise Exception("A socket must be created successfully before attempting "
88
                      "its destruction")
89

  
90
    try:
91
      self.sock.close()
92
    finally:
93
      shutil.rmtree(self.tmpdir)
94

  
95

  
40 96
class LUTestDelay(NoHooksLU):
41 97
  """Sleep for a specified amount of time.
42 98

  
......
118 174
    @param errcls: Exception class to use for errors
119 175

  
120 176
    """
177

  
121 178
    # Using a temporary directory as there's no easy way to create temporary
122 179
    # sockets without writing a custom loop around tempfile.mktemp and
123 180
    # socket.bind
124
    tmpdir = tempfile.mkdtemp()
125
    try:
126
      tmpsock = utils.PathJoin(tmpdir, "sock")
127 181

  
128
      logging.debug("Creating temporary socket at %s", tmpsock)
129
      sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
130
      try:
131
        sock.bind(tmpsock)
132
        sock.listen(1)
133

  
134
        # Send details to client
135
        cb(tmpsock)
136

  
137
        # Wait for client to connect before continuing
138
        sock.settimeout(cls._CLIENT_CONNECT_TIMEOUT)
139
        try:
140
          (conn, _) = sock.accept()
141
        except socket.error, err:
142
          raise errcls("Client didn't connect in time (%s)" % err)
143
      finally:
144
        sock.close()
182
    socket_wrapper = TestSocketWrapper()
183
    sock, path = socket_wrapper.Create()
184

  
185
    cb(path)
186

  
187
    try:
188
      sock.settimeout(cls._CLIENT_CONNECT_TIMEOUT)
189
      (conn, _) = sock.accept()
190
    except socket.error, err:
191
      raise errcls("Client didn't connect in time (%s)" % err)
145 192
    finally:
146
      # Remove as soon as client is connected
147
      shutil.rmtree(tmpdir)
193
      socket_wrapper.Destroy()
148 194

  
149 195
    # Wait for client to close
150 196
    try:

Also available in: Unified diff