~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/tests/process_unittest.py

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-01-21 11:48:06 UTC
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20110121114806-v8fvnnl6az4m4ohv
Tags: upstream-2011.1~bzr597
ImportĀ upstreamĀ versionĀ 2011.1~bzr597

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2010 United States Government as represented by the
4
 
# Administrator of the National Aeronautics and Space Administration.
5
 
# All Rights Reserved.
6
 
#
7
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
8
 
#    not use this file except in compliance with the License. You may obtain
9
 
#    a copy of the License at
10
 
#
11
 
#         http://www.apache.org/licenses/LICENSE-2.0
12
 
#
13
 
#    Unless required by applicable law or agreed to in writing, software
14
 
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
 
#    License for the specific language governing permissions and limitations
17
 
#    under the License.
18
 
 
19
 
import logging
20
 
from twisted.internet import defer
21
 
from twisted.internet import reactor
22
 
from xml.etree import ElementTree
23
 
 
24
 
from nova import exception
25
 
from nova import flags
26
 
from nova import process
27
 
from nova import test
28
 
from nova import utils
29
 
 
30
 
FLAGS = flags.FLAGS
31
 
 
32
 
 
33
 
class ProcessTestCase(test.TrialTestCase):
34
 
    def setUp(self):
35
 
        logging.getLogger().setLevel(logging.DEBUG)
36
 
        super(ProcessTestCase, self).setUp()
37
 
 
38
 
    def test_execute_stdout(self):
39
 
        pool = process.ProcessPool(2)
40
 
        d = pool.simple_execute('echo test')
41
 
 
42
 
        def _check(rv):
43
 
            self.assertEqual(rv[0], 'test\n')
44
 
            self.assertEqual(rv[1], '')
45
 
 
46
 
        d.addCallback(_check)
47
 
        d.addErrback(self.fail)
48
 
        return d
49
 
 
50
 
    def test_execute_stderr(self):
51
 
        pool = process.ProcessPool(2)
52
 
        d = pool.simple_execute('cat BAD_FILE', check_exit_code=False)
53
 
 
54
 
        def _check(rv):
55
 
            self.assertEqual(rv[0], '')
56
 
            self.assert_('No such file' in rv[1])
57
 
 
58
 
        d.addCallback(_check)
59
 
        d.addErrback(self.fail)
60
 
        return d
61
 
 
62
 
    def test_execute_unexpected_stderr(self):
63
 
        pool = process.ProcessPool(2)
64
 
        d = pool.simple_execute('cat BAD_FILE')
65
 
        d.addCallback(lambda x: self.fail('should have raised an error'))
66
 
        d.addErrback(lambda failure: failure.trap(IOError))
67
 
        return d
68
 
 
69
 
    def test_max_processes(self):
70
 
        pool = process.ProcessPool(2)
71
 
        d1 = pool.simple_execute('sleep 0.01')
72
 
        d2 = pool.simple_execute('sleep 0.01')
73
 
        d3 = pool.simple_execute('sleep 0.005')
74
 
        d4 = pool.simple_execute('sleep 0.005')
75
 
 
76
 
        called = []
77
 
 
78
 
        def _called(rv, name):
79
 
            called.append(name)
80
 
 
81
 
        d1.addCallback(_called, 'd1')
82
 
        d2.addCallback(_called, 'd2')
83
 
        d3.addCallback(_called, 'd3')
84
 
        d4.addCallback(_called, 'd4')
85
 
 
86
 
        # Make sure that d3 and d4 had to wait on the other two and were called
87
 
        # in order
88
 
        # NOTE(termie): there may be a race condition in this test if for some
89
 
        #               reason one of the sleeps takes longer to complete
90
 
        #               than it should
91
 
        d4.addCallback(lambda x: self.assertEqual(called[2], 'd3'))
92
 
        d4.addCallback(lambda x: self.assertEqual(called[3], 'd4'))
93
 
        d4.addErrback(self.fail)
94
 
        return d4
95
 
 
96
 
    def test_kill_long_process(self):
97
 
        pool = process.ProcessPool(2)
98
 
 
99
 
        d1 = pool.simple_execute('sleep 1')
100
 
        d2 = pool.simple_execute('sleep 0.005')
101
 
 
102
 
        timeout = reactor.callLater(0.1, self.fail, 'should have been killed')
103
 
 
104
 
        # kill d1 and wait on it to end then cancel the timeout
105
 
        d2.addCallback(lambda _: d1.process.signalProcess('KILL'))
106
 
        d2.addCallback(lambda _: d1)
107
 
        d2.addBoth(lambda _: timeout.active() and timeout.cancel())
108
 
        d2.addErrback(self.fail)
109
 
        return d2
110
 
 
111
 
    def test_process_exit_is_contained(self):
112
 
        pool = process.ProcessPool(2)
113
 
 
114
 
        d1 = pool.simple_execute('sleep 1')
115
 
        d1.addCallback(lambda x: self.fail('should have errbacked'))
116
 
        d1.addErrback(lambda fail: fail.trap(IOError))
117
 
        reactor.callLater(0.05, d1.process.signalProcess, 'KILL')
118
 
 
119
 
        return d1
120
 
 
121
 
    def test_shared_pool_is_singleton(self):
122
 
        pool1 = process.SharedPool()
123
 
        pool2 = process.SharedPool()
124
 
        self.assertEqual(id(pool1._instance), id(pool2._instance))
125
 
 
126
 
    def test_shared_pool_works_as_singleton(self):
127
 
        d1 = process.simple_execute('sleep 1')
128
 
        d2 = process.simple_execute('sleep 0.005')
129
 
        # lp609749: would have failed with
130
 
        # exceptions.AssertionError: Someone released me too many times:
131
 
        # too many tokens!
132
 
        return d1