Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.workerpool_unittest.py @ b705c7a6

History | View | Annotate | Download (5.3 kB)

1 76094e37 Michael Hanselmann
#!/usr/bin/python
2 76094e37 Michael Hanselmann
#
3 76094e37 Michael Hanselmann
4 76094e37 Michael Hanselmann
# Copyright (C) 2008 Google Inc.
5 76094e37 Michael Hanselmann
#
6 76094e37 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 76094e37 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 76094e37 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 76094e37 Michael Hanselmann
# (at your option) any later version.
10 76094e37 Michael Hanselmann
#
11 76094e37 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 76094e37 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 76094e37 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 76094e37 Michael Hanselmann
# General Public License for more details.
15 76094e37 Michael Hanselmann
#
16 76094e37 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 76094e37 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 76094e37 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 76094e37 Michael Hanselmann
# 02110-1301, USA.
20 76094e37 Michael Hanselmann
21 76094e37 Michael Hanselmann
22 76094e37 Michael Hanselmann
"""Script for unittesting the workerpool module"""
23 76094e37 Michael Hanselmann
24 76094e37 Michael Hanselmann
import unittest
25 76094e37 Michael Hanselmann
import threading
26 76094e37 Michael Hanselmann
import time
27 76094e37 Michael Hanselmann
import sys
28 76094e37 Michael Hanselmann
import zlib
29 76094e37 Michael Hanselmann
30 76094e37 Michael Hanselmann
from ganeti import workerpool
31 76094e37 Michael Hanselmann
32 25231ec5 Michael Hanselmann
import testutils
33 25231ec5 Michael Hanselmann
34 7ed3248b Guido Trotter
class CountingContext(object):
35 7ed3248b Guido Trotter
36 7ed3248b Guido Trotter
  def __init__(self):
37 7ed3248b Guido Trotter
    self._lock = threading.Condition(threading.Lock())
38 7ed3248b Guido Trotter
    self.done = 0
39 7ed3248b Guido Trotter
40 7ed3248b Guido Trotter
  def DoneTask(self):
41 7ed3248b Guido Trotter
    self._lock.acquire()
42 7ed3248b Guido Trotter
    try:
43 7ed3248b Guido Trotter
      self.done += 1
44 7ed3248b Guido Trotter
    finally:
45 7ed3248b Guido Trotter
      self._lock.release()
46 7ed3248b Guido Trotter
47 7ed3248b Guido Trotter
  def GetDoneTasks(self):
48 7ed3248b Guido Trotter
    self._lock.acquire()
49 7ed3248b Guido Trotter
    try:
50 7ed3248b Guido Trotter
      return self.done
51 7ed3248b Guido Trotter
    finally:
52 7ed3248b Guido Trotter
      self._lock.release()
53 7ed3248b Guido Trotter
54 7ed3248b Guido Trotter
  @staticmethod
55 7ed3248b Guido Trotter
  def UpdateChecksum(current, value):
56 7ed3248b Guido Trotter
    return zlib.adler32(str(value), current)
57 76094e37 Michael Hanselmann
58 7ed3248b Guido Trotter
59 7ed3248b Guido Trotter
class CountingBaseWorker(workerpool.BaseWorker):
60 7ed3248b Guido Trotter
61 7ed3248b Guido Trotter
  def RunTask(self, ctx, text):
62 7ed3248b Guido Trotter
    ctx.DoneTask()
63 76094e37 Michael Hanselmann
64 76094e37 Michael Hanselmann
65 76094e37 Michael Hanselmann
class ChecksumContext:
66 76094e37 Michael Hanselmann
  CHECKSUM_START = zlib.adler32("")
67 76094e37 Michael Hanselmann
68 76094e37 Michael Hanselmann
  def __init__(self):
69 76094e37 Michael Hanselmann
    self.lock = threading.Condition(threading.Lock())
70 76094e37 Michael Hanselmann
    self.checksum = self.CHECKSUM_START
71 76094e37 Michael Hanselmann
72 76094e37 Michael Hanselmann
  @staticmethod
73 76094e37 Michael Hanselmann
  def UpdateChecksum(current, value):
74 76094e37 Michael Hanselmann
    return zlib.adler32(str(value), current)
75 76094e37 Michael Hanselmann
76 76094e37 Michael Hanselmann
77 76094e37 Michael Hanselmann
class ChecksumBaseWorker(workerpool.BaseWorker):
78 76094e37 Michael Hanselmann
  def RunTask(self, ctx, number):
79 76094e37 Michael Hanselmann
    ctx.lock.acquire()
80 76094e37 Michael Hanselmann
    try:
81 76094e37 Michael Hanselmann
      ctx.checksum = ctx.UpdateChecksum(ctx.checksum, number)
82 76094e37 Michael Hanselmann
    finally:
83 76094e37 Michael Hanselmann
      ctx.lock.release()
84 76094e37 Michael Hanselmann
85 76094e37 Michael Hanselmann
86 76094e37 Michael Hanselmann
class TestWorkerpool(unittest.TestCase):
87 76094e37 Michael Hanselmann
  """Workerpool tests"""
88 76094e37 Michael Hanselmann
89 7ed3248b Guido Trotter
  def testCounting(self):
90 7ed3248b Guido Trotter
    ctx = CountingContext()
91 7ed3248b Guido Trotter
    wp = workerpool.WorkerPool("Test", 3, CountingBaseWorker)
92 76094e37 Michael Hanselmann
    try:
93 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 3)
94 76094e37 Michael Hanselmann
95 f1501b3f Michael Hanselmann
      for i in range(10):
96 b2e8a4d9 Michael Hanselmann
        wp.AddTask((ctx, "Hello world %s" % i))
97 76094e37 Michael Hanselmann
98 76094e37 Michael Hanselmann
      wp.Quiesce()
99 76094e37 Michael Hanselmann
    finally:
100 76094e37 Michael Hanselmann
      wp.TerminateWorkers()
101 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 0)
102 76094e37 Michael Hanselmann
103 7ed3248b Guido Trotter
    self.assertEquals(ctx.GetDoneTasks(), 10)
104 7ed3248b Guido Trotter
105 76094e37 Michael Hanselmann
  def testNoTasks(self):
106 7ed3248b Guido Trotter
    wp = workerpool.WorkerPool("Test", 3, CountingBaseWorker)
107 76094e37 Michael Hanselmann
    try:
108 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 3)
109 76094e37 Michael Hanselmann
      self._CheckNoTasks(wp)
110 76094e37 Michael Hanselmann
    finally:
111 76094e37 Michael Hanselmann
      wp.TerminateWorkers()
112 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 0)
113 76094e37 Michael Hanselmann
114 76094e37 Michael Hanselmann
  def testNoTasksQuiesce(self):
115 7ed3248b Guido Trotter
    wp = workerpool.WorkerPool("Test", 3, CountingBaseWorker)
116 76094e37 Michael Hanselmann
    try:
117 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 3)
118 76094e37 Michael Hanselmann
      self._CheckNoTasks(wp)
119 76094e37 Michael Hanselmann
      wp.Quiesce()
120 76094e37 Michael Hanselmann
      self._CheckNoTasks(wp)
121 76094e37 Michael Hanselmann
    finally:
122 76094e37 Michael Hanselmann
      wp.TerminateWorkers()
123 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 0)
124 76094e37 Michael Hanselmann
125 76094e37 Michael Hanselmann
  def testChecksum(self):
126 76094e37 Michael Hanselmann
    # Tests whether all tasks are run and, since we're only using a single
127 76094e37 Michael Hanselmann
    # thread, whether everything is started in order.
128 89e2b4d2 Michael Hanselmann
    wp = workerpool.WorkerPool("Test", 1, ChecksumBaseWorker)
129 76094e37 Michael Hanselmann
    try:
130 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 1)
131 76094e37 Michael Hanselmann
132 76094e37 Michael Hanselmann
      ctx = ChecksumContext()
133 76094e37 Michael Hanselmann
      checksum = ChecksumContext.CHECKSUM_START
134 f1501b3f Michael Hanselmann
      for i in range(1, 100):
135 76094e37 Michael Hanselmann
        checksum = ChecksumContext.UpdateChecksum(checksum, i)
136 b2e8a4d9 Michael Hanselmann
        wp.AddTask((ctx, i))
137 76094e37 Michael Hanselmann
138 76094e37 Michael Hanselmann
      wp.Quiesce()
139 76094e37 Michael Hanselmann
140 76094e37 Michael Hanselmann
      self._CheckNoTasks(wp)
141 76094e37 Michael Hanselmann
142 76094e37 Michael Hanselmann
      # Check sum
143 76094e37 Michael Hanselmann
      ctx.lock.acquire()
144 76094e37 Michael Hanselmann
      try:
145 76094e37 Michael Hanselmann
        self.assertEqual(checksum, ctx.checksum)
146 76094e37 Michael Hanselmann
      finally:
147 76094e37 Michael Hanselmann
        ctx.lock.release()
148 76094e37 Michael Hanselmann
    finally:
149 76094e37 Michael Hanselmann
      wp.TerminateWorkers()
150 76094e37 Michael Hanselmann
      self._CheckWorkerCount(wp, 0)
151 76094e37 Michael Hanselmann
152 c2a8e8ba Guido Trotter
  def testAddManyTasks(self):
153 7ed3248b Guido Trotter
    ctx = CountingContext()
154 7ed3248b Guido Trotter
    wp = workerpool.WorkerPool("Test", 3, CountingBaseWorker)
155 c2a8e8ba Guido Trotter
    try:
156 c2a8e8ba Guido Trotter
      self._CheckWorkerCount(wp, 3)
157 c2a8e8ba Guido Trotter
158 7ed3248b Guido Trotter
      wp.AddManyTasks([(ctx, "Hello world %s" % i, ) for i in range(10)])
159 b2e8a4d9 Michael Hanselmann
      wp.AddTask((ctx, "A separate hello"))
160 b2e8a4d9 Michael Hanselmann
      wp.AddTask((ctx, "Once more, hi!"))
161 7ed3248b Guido Trotter
      wp.AddManyTasks([(ctx, "Hello world %s" % i, ) for i in range(10)])
162 c2a8e8ba Guido Trotter
163 c2a8e8ba Guido Trotter
      wp.Quiesce()
164 c2a8e8ba Guido Trotter
165 c2a8e8ba Guido Trotter
      self._CheckNoTasks(wp)
166 c2a8e8ba Guido Trotter
    finally:
167 c2a8e8ba Guido Trotter
      wp.TerminateWorkers()
168 c2a8e8ba Guido Trotter
      self._CheckWorkerCount(wp, 0)
169 c2a8e8ba Guido Trotter
170 7ed3248b Guido Trotter
    self.assertEquals(ctx.GetDoneTasks(), 22)
171 7ed3248b Guido Trotter
172 25e557a5 Guido Trotter
  def testManyTasksSequence(self):
173 25e557a5 Guido Trotter
    ctx = CountingContext()
174 25e557a5 Guido Trotter
    wp = workerpool.WorkerPool("Test", 3, CountingBaseWorker)
175 25e557a5 Guido Trotter
    try:
176 25e557a5 Guido Trotter
      self._CheckWorkerCount(wp, 3)
177 25e557a5 Guido Trotter
      self.assertRaises(AssertionError, wp.AddManyTasks,
178 25e557a5 Guido Trotter
                        ["Hello world %s" % i for i in range(10)])
179 25e557a5 Guido Trotter
      self.assertRaises(AssertionError, wp.AddManyTasks,
180 25e557a5 Guido Trotter
                        [i for i in range(10)])
181 25e557a5 Guido Trotter
182 25e557a5 Guido Trotter
      wp.AddManyTasks([(ctx, "Hello world %s" % i, ) for i in range(10)])
183 b2e8a4d9 Michael Hanselmann
      wp.AddTask((ctx, "A separate hello"))
184 25e557a5 Guido Trotter
185 25e557a5 Guido Trotter
      wp.Quiesce()
186 25e557a5 Guido Trotter
187 25e557a5 Guido Trotter
      self._CheckNoTasks(wp)
188 25e557a5 Guido Trotter
    finally:
189 25e557a5 Guido Trotter
      wp.TerminateWorkers()
190 25e557a5 Guido Trotter
      self._CheckWorkerCount(wp, 0)
191 25e557a5 Guido Trotter
192 25e557a5 Guido Trotter
    self.assertEquals(ctx.GetDoneTasks(), 11)
193 25e557a5 Guido Trotter
194 76094e37 Michael Hanselmann
  def _CheckNoTasks(self, wp):
195 76094e37 Michael Hanselmann
    wp._lock.acquire()
196 76094e37 Michael Hanselmann
    try:
197 76094e37 Michael Hanselmann
      # The task queue must be empty now
198 76094e37 Michael Hanselmann
      self.failUnless(not wp._tasks)
199 76094e37 Michael Hanselmann
    finally:
200 76094e37 Michael Hanselmann
      wp._lock.release()
201 76094e37 Michael Hanselmann
202 76094e37 Michael Hanselmann
  def _CheckWorkerCount(self, wp, num_workers):
203 76094e37 Michael Hanselmann
    wp._lock.acquire()
204 76094e37 Michael Hanselmann
    try:
205 76094e37 Michael Hanselmann
      self.assertEqual(len(wp._workers), num_workers)
206 76094e37 Michael Hanselmann
    finally:
207 76094e37 Michael Hanselmann
      wp._lock.release()
208 76094e37 Michael Hanselmann
209 76094e37 Michael Hanselmann
210 76094e37 Michael Hanselmann
if __name__ == '__main__':
211 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()