~jaypipes/glance/bug704854

« back to all changes in this revision

Viewing changes to tests/unit/test_misc.py

  • Committer: jaypipes at gmail
  • Date: 2011-02-22 15:53:32 UTC
  • Revision ID: jaypipes@gmail.com-20110222155332-fx0b0wp4a918jjp6
I should probably rebase this commit considering all the previous
commits weren't actually addressing the issue. The fact that I
had glance-api and glance-registry installed on my local machine
was causing the test runs to improperly return a passing result.

It just so happens that the glance-api and glance-registry that
I had installed to my /usr/local/bin were the very same programs
that were from a previous branch I had locally where I fixed the
root cause of this issue, which was that the sqlalchemy @validates
decorator does NOT fire for *new* objects, only existing ones, which
resulted in image_create() improperly storing NULL data in type, name,
and other non-nullable fields in the database. This then set off
a domino effect which caused the next call from
glance.server._upload_and_activate() to die a horrible death due to
the @validates decorator then firing on the already-created Image
object. This horrible death was improperly being raised from the
glance.client as a BadRequest instead of exception.Invalid, which
caused the API server to ignore the text in the actual Invalid
exception coming from the registry server.

In short, this patch finally fixes the root of the problem by
placing a validate_image() function guard which throws exception.Invalid
for any invalid data coming into the _image_update() method in the db
API. It also adds a bunch of logging statements and ensures that
exceptions throughout the call stack between the API server to the
glance.registry.Client to the Registry server are properly handled and
that the text of those exceptions isn't thrown away willy-nilly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
 
27
27
def execute(cmd):
 
28
    env = os.environ.copy()
 
29
    # Make sure that we use the programs in the
 
30
    # current source directory's bin/ directory.
 
31
    env['PATH'] = os.path.join(os.getcwd(), 'bin') + ':' + env['PATH']
28
32
    process = subprocess.Popen(cmd,
29
33
                               shell=True,
30
34
                               stdin=subprocess.PIPE,
31
35
                               stdout=subprocess.PIPE,
32
36
                               stderr=subprocess.PIPE,
33
 
                               env=os.environ.copy())
 
37
                               env=env)
34
38
    result = process.communicate()
35
39
    (out, err) = result
 
40
    exitcode = process.returncode
36
41
    if process.returncode != 0:
37
 
        exitcode = process.returncode
38
42
        msg = "Command %(cmd)s did not succeed. Returned an exit "\
39
43
              "code of %(exitcode)d."\
40
44
              "\n\nSTDOUT: %(out)s"\
41
45
              "\n\nSTDERR: %(err)s" % locals()
42
46
        raise RuntimeError(msg)
43
 
    return out, err
 
47
    return exitcode, out, err
44
48
 
45
49
 
46
50
class TestMiscellaneous(unittest.TestCase):
120
124
            # Start up the API and default registry server
121
125
            cmd = venv + "./bin/glance-control api start "\
122
126
                         "%s --pid-file=glance-api.pid" % conf_file
123
 
            out, err = execute(cmd)
 
127
            exitcode, out, err = execute(cmd)
 
128
 
 
129
            self.assertEquals(0, exitcode)
 
130
            self.assertTrue("Starting glance-api with" in out)
124
131
 
125
132
            cmd = venv + "./bin/glance-control registry start "\
126
133
                         "%s --pid-file=glance-registry.pid" % conf_file
127
 
            out, err = execute(cmd)
 
134
            exitcode, out, err = execute(cmd)
 
135
 
 
136
            self.assertEquals(0, exitcode)
 
137
            self.assertTrue("Starting glance-registry with" in out)
128
138
 
129
139
            time.sleep(2)  # Gotta give some time for spin up...
130
140
 
131
141
            cmd = "curl -g http://0.0.0.0:%d/images" % api_port
132
142
 
133
 
            out, err = execute(cmd)
 
143
            exitcode, out, err = execute(cmd)
134
144
 
 
145
            self.assertEquals(0, exitcode)
135
146
            self.assertEquals('{"images": []}', out.strip())
136
147
 
137
 
            cmd = "curl -X POST -dinvalid http://0.0.0.0:%d/images" % api_port
138
 
            out, err = execute(cmd)
 
148
            cmd = "curl -X POST -H 'Content-Type: application/octet-stream' "\
 
149
                  "-dinvalid http://0.0.0.0:%d/images" % api_port
 
150
            ignored, out, err = execute(cmd)
139
151
 
140
152
            self.assertTrue('Image type is required' in out,
141
153
                            "Could not find 'Image type is required' "
149
161
            # the exception text...
150
162
            hit_exception = False
151
163
            try:
152
 
                out, err = execute(cmd)
 
164
                ignored, out, err = execute(cmd)
153
165
            except RuntimeError, e:
154
166
                hit_exception = True
155
167
                self.assertTrue('Invalid image type' in str(e))
158
170
            # Spin down the API and default registry server
159
171
            cmd = "./bin/glance-control api stop "\
160
172
                  "%s --pid-file=glance-api.pid" % conf_file
161
 
            out, err = execute(cmd)
 
173
            ignored, out, err = execute(cmd)
162
174
            cmd = "./bin/glance-control registry stop "\
163
175
                  "%s --pid-file=glance-registry.pid" % conf_file
164
 
            out, err = execute(cmd)
 
176
            ignored, out, err = execute(cmd)