Fix race in dib_image_list_json test
Change Ibff0a9016936b461eccb1b48dcf42f5ad8d8434e had an error that was not caught by testing due to a race in the test code -- the build might finish before the webapp starts. This corrects the test (and a few sibling tests) by starting the webapp first, then starting the builder. The actual error is also corrected: ImageBuild.updateFromDict is implemented. Further, duplicate fromDict method calls are removed from several classes and renamed to updateFromDict so that the APIs match. Change-Id: I918d1badf838a23d6b0813b5b31dac4888d04ce0
This commit is contained in:
@@ -34,12 +34,15 @@ class TestWebApp(tests.DBTestCase):
|
||||
def test_image_list(self):
|
||||
configfile = self.setup_config('node.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self.useBuilder(configfile)
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
# Start the builder after the pool + webapp so they see the
|
||||
# cache update
|
||||
self.useBuilder(configfile)
|
||||
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
self.waitForNodes('fake-label')
|
||||
|
||||
@@ -68,12 +71,15 @@ class TestWebApp(tests.DBTestCase):
|
||||
def test_image_list_filtered(self):
|
||||
configfile = self.setup_config('node.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self.useBuilder(configfile)
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
# Start the builder after the pool + webapp so they see the
|
||||
# cache update
|
||||
self.useBuilder(configfile)
|
||||
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
self.waitForNodes('fake-label')
|
||||
|
||||
@@ -90,12 +96,15 @@ class TestWebApp(tests.DBTestCase):
|
||||
def test_image_list_json(self):
|
||||
configfile = self.setup_config('node.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self.useBuilder(configfile)
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
# Start the builder after the pool + webapp so they see the
|
||||
# cache update
|
||||
self.useBuilder(configfile)
|
||||
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
self.waitForNodes('fake-label')
|
||||
|
||||
@@ -115,12 +124,15 @@ class TestWebApp(tests.DBTestCase):
|
||||
def test_dib_image_list_json(self):
|
||||
configfile = self.setup_config('node.yaml')
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
self.useBuilder(configfile)
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
# Start the builder after the pool + webapp so they see the
|
||||
# cache update
|
||||
self.useBuilder(configfile)
|
||||
|
||||
self.waitForImage('fake-provider', 'fake-image')
|
||||
self.waitForNodes('fake-label')
|
||||
|
||||
@@ -141,17 +153,18 @@ class TestWebApp(tests.DBTestCase):
|
||||
def test_image_status_json(self):
|
||||
configfile = self.setup_config("node.yaml")
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
builder = self.useBuilder(configfile)
|
||||
# Make sure we have enough time to test for the build request
|
||||
# before it's processed by the build worker.
|
||||
for worker in builder._build_workers:
|
||||
worker._interval = 60
|
||||
|
||||
pool.start()
|
||||
webapp = self.useWebApp(pool, port=0)
|
||||
webapp.start()
|
||||
port = webapp.server.socket.getsockname()[1]
|
||||
|
||||
builder = self.useBuilder(configfile)
|
||||
# Make sure we have enough time to test for the build request
|
||||
# before it's processed by the build worker.
|
||||
for worker in builder._build_workers:
|
||||
worker._interval = 60
|
||||
|
||||
self.waitForImage("fake-provider", "fake-image")
|
||||
self.waitForNodes('fake-label')
|
||||
|
||||
|
||||
@@ -159,12 +159,9 @@ class BaseModel(Serializable):
|
||||
d['state_time'] = self.state_time
|
||||
return d
|
||||
|
||||
def fromDict(self, d):
|
||||
def updateFromDict(self, d):
|
||||
'''
|
||||
Set base attributes based on the given dict.
|
||||
|
||||
Unlike the derived classes, this should NOT return an object as it
|
||||
assumes self has already been instantiated.
|
||||
'''
|
||||
if 'state' in d:
|
||||
self.state = d['state']
|
||||
@@ -241,16 +238,19 @@ class ImageBuild(BaseModel):
|
||||
:returns: An initialized ImageBuild object.
|
||||
'''
|
||||
o = ImageBuild(image_name, o_id)
|
||||
super(ImageBuild, o).fromDict(d)
|
||||
o.builder = d.get('builder')
|
||||
o.builder_id = d.get('builder_id')
|
||||
o.username = d.get('username', 'zuul')
|
||||
o.python_path = d.get('python_path', '/usr/bin/python2')
|
||||
o.shell_type = d.get('shell_type')
|
||||
o.updateFromDict(d)
|
||||
return o
|
||||
|
||||
def updateFromDict(self, d):
|
||||
super().updateFromDict(d)
|
||||
self.builder = d.get('builder')
|
||||
self.builder_id = d.get('builder_id')
|
||||
self.username = d.get('username', 'zuul')
|
||||
self.python_path = d.get('python_path', '/usr/bin/python2')
|
||||
self.shell_type = d.get('shell_type')
|
||||
# Only attempt the split on non-empty string
|
||||
if d.get('formats', ''):
|
||||
o.formats = d.get('formats', '').split(',')
|
||||
return o
|
||||
self.formats = d.get('formats', '').split(',')
|
||||
|
||||
|
||||
class ImageBuildRequest(object):
|
||||
@@ -351,12 +351,11 @@ class ImageUpload(BaseModel):
|
||||
:returns: An initialized ImageUpload object.
|
||||
'''
|
||||
o = ImageUpload(build_id, provider_name, image_name, upload_id)
|
||||
super(ImageUpload, o).fromDict(d)
|
||||
o.updateFromDict(d)
|
||||
return o
|
||||
|
||||
def updateFromDict(self, d):
|
||||
super().fromDict(d)
|
||||
super().updateFromDict(d)
|
||||
self.external_id = d.get('external_id')
|
||||
self.external_name = d.get('external_name')
|
||||
self.format = d.get('format')
|
||||
@@ -468,12 +467,11 @@ class NodeRequest(BaseModel):
|
||||
:returns: An initialized NodeRequest object.
|
||||
'''
|
||||
o = NodeRequest(o_id)
|
||||
super(NodeRequest, o).fromDict(d)
|
||||
o.updateFromDict(d)
|
||||
return o
|
||||
|
||||
def updateFromDict(self, d):
|
||||
super().fromDict(d)
|
||||
super().updateFromDict(d)
|
||||
self.declined_by = d.get('declined_by', [])
|
||||
self.node_types = d.get('node_types', [])
|
||||
self.nodes = d.get('nodes', [])
|
||||
@@ -661,8 +659,6 @@ class Node(BaseModel):
|
||||
:returns: An initialized Node object.
|
||||
'''
|
||||
o = Node(o_id)
|
||||
super(Node, o).fromDict(d)
|
||||
|
||||
o.updateFromDict(d)
|
||||
return o
|
||||
|
||||
@@ -672,7 +668,7 @@ class Node(BaseModel):
|
||||
|
||||
:param dict d: The dictionary
|
||||
'''
|
||||
super().fromDict(d)
|
||||
super().updateFromDict(d)
|
||||
self.cloud = d.get('cloud')
|
||||
self.provider = d.get('provider')
|
||||
self.pool = d.get('pool')
|
||||
|
||||
Reference in New Issue
Block a user