From 11f4046b69c969920c8593251f5dc716940454be Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Fri, 5 Jul 2013 21:42:31 +1000 Subject: [PATCH] Stop patching the GenericResource's property_schema This is causing test failures if you add a new test and don't reset the scema to {}, this seems to be timing related. Just add Resource types that we need prevents the need for this patching. Change-Id: If7ddd2b1ffa8b54025c0369fe8c4f7440f0e3cdc --- heat/tests/generic_resource.py | 9 ++++ heat/tests/test_event.py | 19 +++---- heat/tests/test_parser.py | 82 ++++++++++-------------------- heat/tests/test_resource.py | 91 ++++++---------------------------- 4 files changed, 58 insertions(+), 143 deletions(-) diff --git a/heat/tests/generic_resource.py b/heat/tests/generic_resource.py index 765642c0f0..26a7eec60f 100644 --- a/heat/tests/generic_resource.py +++ b/heat/tests/generic_resource.py @@ -41,3 +41,12 @@ class GenericResource(resource.Resource): def handle_resume(self): logger.warning('Resuming generic resource (Type "%s")' % self.type()) + + +class ResourceWithProps(GenericResource): + properties_schema = {'Foo': {'Type': 'String'}} + + +class ResourceWithRequiredProps(GenericResource): + properties_schema = {'Foo': {'Type': 'String', + 'Required': True}} diff --git a/heat/tests/test_event.py b/heat/tests/test_event.py index 8e23a584dd..160eba42ed 100644 --- a/heat/tests/test_event.py +++ b/heat/tests/test_event.py @@ -28,8 +28,8 @@ from heat.tests import generic_resource as generic_rsrc tmpl = { 'Resources': { 'EventTestResource': { - 'Type': 'GenericResourceType', - 'Properties': {'foo': True} + 'Type': 'ResourceWithRequiredProps', + 'Properties': {'Foo': 'goo'} } } } @@ -48,12 +48,8 @@ class EventTest(HeatTestCase): self.m.ReplayAll() - # patch in a dummy property schema for GenericResource - dummy_schema = {'foo': {'Type': 'Boolean', 'Required': True}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - resource._register_class('GenericResourceType', - generic_rsrc.GenericResource) + resource._register_class('ResourceWithRequiredProps', + generic_rsrc.ResourceWithRequiredProps) self.stack = parser.Stack(self.ctx, 'event_load_test_stack', template.Template(tmpl)) @@ -83,7 +79,7 @@ class EventTest(HeatTestCase): self.assertEqual(loaded_e.status, 'IN_PROGRESS') self.assertEqual(loaded_e.reason, 'Testing') self.assertNotEqual(loaded_e.timestamp, None) - self.assertEqual(loaded_e.resource_properties, {'foo': True}) + self.assertEqual(loaded_e.resource_properties, {'Foo': 'goo'}) def test_identifier(self): e = event.Event(self.ctx, self.stack, self.resource, @@ -100,9 +96,10 @@ class EventTest(HeatTestCase): self.assertEqual(e.identifier(), expected_identifier) def test_badprop(self): - tmpl = {'Type': 'GenericResourceType', 'Properties': {'foo': 'abc'}} + tmpl = {'Type': 'ResourceWithRequiredProps', + 'Properties': {'Foo': False}} rname = 'bad_resource' - res = generic_rsrc.GenericResource(rname, tmpl, self.stack) + res = generic_rsrc.ResourceWithRequiredProps(rname, tmpl, self.stack) e = event.Event(self.ctx, self.stack, res, 'TEST', 'IN_PROGRESS', 'Testing', 'wibble', res.properties) diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index b77f3801e2..82f47ca7ab 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -519,9 +519,10 @@ class StackTest(HeatTestCase): self.ctx.user = self.username self.ctx.tenant_id = 'test_tenant' - generic_rsrc.GenericResource.properties_schema = {} resource._register_class('GenericResourceType', generic_rsrc.GenericResource) + resource._register_class('ResourceWithPropsType', + generic_rsrc.ResourceWithProps) self.m.ReplayAll() @@ -946,11 +947,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_modify_ok_replace(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -964,7 +961,7 @@ class StackTest(HeatTestCase): self.assertEqual(self.stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -983,11 +980,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_modify_update_failed(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -1006,7 +999,7 @@ class StackTest(HeatTestCase): res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -1028,11 +1021,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_modify_replace_failed_delete(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -1047,7 +1036,7 @@ class StackTest(HeatTestCase): self.assertEqual(self.stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -1072,11 +1061,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_modify_replace_failed_create(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -1091,7 +1076,7 @@ class StackTest(HeatTestCase): self.assertEqual(self.stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -1149,11 +1134,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_rollback(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -1168,7 +1149,7 @@ class StackTest(HeatTestCase): self.assertEqual(self.stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -1193,11 +1174,7 @@ class StackTest(HeatTestCase): @stack_delete_after def test_update_rollback_fail(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - - tmpl = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}}} self.m.StubOutWithMock(scheduler.TaskRunner, '_sleep') @@ -1212,7 +1189,7 @@ class StackTest(HeatTestCase): self.assertEqual(self.stack.state, (parser.Stack.CREATE, parser.Stack.COMPLETE)) - tmpl2 = {'Resources': {'AResource': {'Type': 'GenericResourceType', + tmpl2 = {'Resources': {'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'xyz'}}}} updated_stack = parser.Stack(self.ctx, 'updated_stack', @@ -1313,19 +1290,16 @@ class StackTest(HeatTestCase): changes in dynamic attributes, due to other resources been updated are not ignored and can cause dependant resources to be updated. ''' - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema tmpl = {'Resources': { - 'AResource': {'Type': 'GenericResourceType', + 'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} tmpl2 = {'Resources': { - 'AResource': {'Type': 'GenericResourceType', + 'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'smelly'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} @@ -1372,19 +1346,16 @@ class StackTest(HeatTestCase): check that rollback still works with dynamic metadata this test fails the first instance ''' - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema tmpl = {'Resources': { - 'AResource': {'Type': 'GenericResourceType', + 'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'abc'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} tmpl2 = {'Resources': { - 'AResource': {'Type': 'GenericResourceType', + 'AResource': {'Type': 'ResourceWithPropsType', 'Properties': {'Foo': 'smelly'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} @@ -1443,7 +1414,7 @@ class StackTest(HeatTestCase): this test fails the second instance ''' - class ResourceTypeA(generic_rsrc.GenericResource): + class ResourceTypeA(generic_rsrc.ResourceWithProps): count = 0 def handle_create(self): @@ -1452,19 +1423,16 @@ class StackTest(HeatTestCase): resource._register_class('ResourceTypeA', ResourceTypeA) - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema tmpl = {'Resources': { 'AResource': {'Type': 'ResourceTypeA', 'Properties': {'Foo': 'abc'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} tmpl2 = {'Resources': { 'AResource': {'Type': 'ResourceTypeA', 'Properties': {'Foo': 'smelly'}}, - 'BResource': {'Type': 'GenericResourceType', + 'BResource': {'Type': 'ResourceWithPropsType', 'Properties': { 'Foo': {'Ref': 'AResource'}}}}} diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 331a3bd3db..3b270b64dc 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -247,23 +247,15 @@ class ResourceTest(HeatTestCase): update_snippet, tmpl) def test_resource(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) def test_create_fail_missing_req_prop(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String', 'Required': True}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {}} rname = 'test_resource' - res = generic_rsrc.GenericResource(rname, tmpl, self.stack) + res = generic_rsrc.ResourceWithRequiredProps(rname, tmpl, self.stack) estr = 'Property error : test_resource: Property Foo not assigned' create = scheduler.TaskRunner(res.create) @@ -271,13 +263,9 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.CREATE, res.FAILED), res.state) def test_create_fail_prop_typo(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String', 'Required': True}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Food': 'abc'}} rname = 'test_resource' - res = generic_rsrc.GenericResource(rname, tmpl, self.stack) + res = generic_rsrc.ResourceWithProps(rname, tmpl, self.stack) estr = 'Property error : test_resource: Property Foo not assigned' create = scheduler.TaskRunner(res.create) @@ -285,12 +273,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.CREATE, res.FAILED), res.state) def test_update_ok(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -309,12 +293,8 @@ class ResourceTest(HeatTestCase): self.m.VerifyAll() def test_update_replace(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -332,12 +312,9 @@ class ResourceTest(HeatTestCase): self.m.VerifyAll() def test_update_fail_missing_req_prop(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String', 'Required': True}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithRequiredProps('test_resource', + tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -349,12 +326,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.UPDATE, res.FAILED), res.state) def test_update_fail_prop_typo(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -366,12 +339,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.UPDATE, res.FAILED), res.state) def test_update_not_implemented(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -389,12 +358,8 @@ class ResourceTest(HeatTestCase): self.m.VerifyAll() def test_suspend_resume_ok(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) res.update_allowed_keys = ('Properties',) res.update_allowed_properties = ('Foo',) scheduler.TaskRunner(res.create)() @@ -405,12 +370,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.RESUME, res.COMPLETE), res.state) def test_suspend_fail_inprogress(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) @@ -427,12 +388,8 @@ class ResourceTest(HeatTestCase): self.assertRaises(exception.ResourceFailure, suspend) def test_resume_fail_not_suspend_complete(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) @@ -445,12 +402,8 @@ class ResourceTest(HeatTestCase): self.assertRaises(exception.ResourceFailure, resume) def test_suspend_fail_exit(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) @@ -464,12 +417,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.SUSPEND, res.FAILED), res.state) def test_resume_fail_exit(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) @@ -485,12 +434,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.RESUME, res.FAILED), res.state) def test_suspend_fail_exception(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state) @@ -503,12 +448,8 @@ class ResourceTest(HeatTestCase): self.assertEqual((res.SUSPEND, res.FAILED), res.state) def test_resume_fail_exception(self): - # patch in a dummy property schema for GenericResource - dummy_schema = {'Foo': {'Type': 'String'}} - generic_rsrc.GenericResource.properties_schema = dummy_schema - tmpl = {'Type': 'GenericResourceType', 'Properties': {'Foo': 'abc'}} - res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack) + res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack) scheduler.TaskRunner(res.create)() self.assertEqual((res.CREATE, res.COMPLETE), res.state)