@@ -29,6 +29,56 @@ class TestResource(unittest.TestCase):
2929 def setUp (self ) -> None :
3030 logging .configure (level = logging .Level .DISABLED )
3131
32+ def test_update_status (self ) -> None :
33+ @dataclasses .dataclass
34+ class TestCase :
35+ reason : str
36+ r : fnv1 .Resource
37+ status : dict | pydantic .BaseModel
38+ want : dict
39+
40+ cases = [
41+ TestCase (
42+ reason = "Setting status from a dict should work." ,
43+ r = fnv1 .Resource (
44+ resource = resource .dict_to_struct (
45+ {"apiVersion" : "example.org" , "kind" : "XR" }
46+ ),
47+ ),
48+ status = {"ready" : True },
49+ want = {
50+ "apiVersion" : "example.org" ,
51+ "kind" : "XR" ,
52+ "status" : {"ready" : True },
53+ },
54+ ),
55+ TestCase (
56+ reason = "Setting status from a Pydantic model should work." ,
57+ r = fnv1 .Resource (
58+ resource = resource .dict_to_struct (
59+ {"apiVersion" : "example.org" , "kind" : "XR" }
60+ ),
61+ ),
62+ status = v1beta2 .ForProvider (region = "us-west-2" ),
63+ want = {
64+ "apiVersion" : "example.org" ,
65+ "kind" : "XR" ,
66+ "status" : {"region" : "us-west-2" },
67+ },
68+ ),
69+ TestCase (
70+ reason = "Setting status on an empty resource should work." ,
71+ r = fnv1 .Resource (),
72+ status = {"replicas" : 3 },
73+ want = {"status" : {"replicas" : 3 }},
74+ ),
75+ ]
76+
77+ for case in cases :
78+ resource .update_status (case .r , case .status )
79+ got = resource .struct_to_dict (case .r .resource )
80+ self .assertEqual (case .want , got , case .reason )
81+
3282 def test_add (self ) -> None :
3383 @dataclasses .dataclass
3484 class TestCase :
@@ -112,11 +162,17 @@ def test_get_condition(self) -> None:
112162 @dataclasses .dataclass
113163 class TestCase :
114164 reason : str
115- res : structpb .Struct
165+ res : structpb .Struct | fnv1 . Resource | None
116166 typ : str
117167 want : resource .Condition
118168
119169 cases = [
170+ TestCase (
171+ reason = "Return an unknown condition if the resource is None." ,
172+ res = None ,
173+ typ = "Ready" ,
174+ want = resource .Condition (typ = "Ready" , status = "Unknown" ),
175+ ),
120176 TestCase (
121177 reason = "Return an unknown condition if the resource has no status." ,
122178 res = resource .dict_to_struct ({}),
@@ -197,6 +253,31 @@ class TestCase:
197253 ),
198254 ),
199255 ),
256+ TestCase (
257+ reason = "Unwrap an fnv1.Resource to get the condition from its Struct." ,
258+ res = fnv1 .Resource (
259+ resource = resource .dict_to_struct (
260+ {
261+ "status" : {
262+ "conditions" : [
263+ {
264+ "type" : "Ready" ,
265+ "status" : "True" ,
266+ }
267+ ]
268+ }
269+ }
270+ ),
271+ ),
272+ typ = "Ready" ,
273+ want = resource .Condition (typ = "Ready" , status = "True" ),
274+ ),
275+ TestCase (
276+ reason = "Return an unknown condition from an empty fnv1.Resource." ,
277+ res = fnv1 .Resource (),
278+ typ = "Ready" ,
279+ want = resource .Condition (typ = "Ready" , status = "Unknown" ),
280+ ),
200281 ]
201282
202283 for case in cases :
@@ -324,6 +405,59 @@ class TestCase:
324405 got = resource .struct_to_dict (case .s )
325406 self .assertEqual (case .want , got , "-want, +got" )
326407
408+ def test_child_name (self ) -> None :
409+ @dataclasses .dataclass
410+ class TestCase :
411+ reason : str
412+ parts : list [str ]
413+ want : str
414+
415+ cases = [
416+ TestCase (
417+ reason = "A short name should be joined with a hash suffix." ,
418+ parts = ["my-xr" , "bucket" ],
419+ want = "my-xr-bucket-05ecb" ,
420+ ),
421+ TestCase (
422+ reason = "A single part should get a hash suffix." ,
423+ parts = ["my-xr" ],
424+ want = "my-xr-9d53f" ,
425+ ),
426+ TestCase (
427+ reason = "A long name should be truncated to fit within 63 characters." ,
428+ parts = ["a" * 40 , "b" * 40 ],
429+ want = "a" * 40 + "-" + "b" * 16 + "-" + "f5e42" ,
430+ ),
431+ TestCase (
432+ reason = "A name that would end with a trailing separator "
433+ "after truncation should have the separator stripped." ,
434+ parts = ["a" * 56 + "-" , "x" ],
435+ # Without stripping, this would be "aaa..a--<hash>".
436+ # The trailing separator from the truncation is stripped.
437+ want = "a" * 56 + "-" + "995eb" ,
438+ ),
439+ TestCase (
440+ reason = "The same inputs should always produce the same name." ,
441+ parts = ["parent" , "child" ],
442+ want = "parent-child-2f0c9" ,
443+ ),
444+ ]
445+
446+ for case in cases :
447+ got = resource .child_name (* case .parts )
448+ self .assertEqual (case .want , got , case .reason )
449+ self .assertLessEqual (len (got ), 63 , case .reason )
450+
451+ def test_child_name_deterministic (self ) -> None :
452+ a = resource .child_name ("parent" , "child" )
453+ b = resource .child_name ("parent" , "child" )
454+ self .assertEqual (a , b )
455+
456+ def test_child_name_unique (self ) -> None :
457+ a = resource .child_name ("parent" , "child-a" )
458+ b = resource .child_name ("parent" , "child-b" )
459+ self .assertNotEqual (a , b )
460+
327461
328462if __name__ == "__main__" :
329463 unittest .main ()
0 commit comments