@@ -705,6 +705,75 @@ func TestUpdatedRelatedObjects(t *testing.T) {
705705 assert .Equal (t , "bar" , relatedList [0 ].Object .Metadata .Name )
706706}
707707
708+ func TestAddRelatedObjectProperties (t * testing.T ) {
709+ compliant := true
710+ scopedGVR := depclient.ScopedGVR {
711+ GroupVersionResource : policyv1 .SchemeBuilder .GroupVersion .WithResource ("ConfigurationPolicy" ),
712+ Namespaced : true ,
713+ }
714+ namespace := "default"
715+ name := "foo"
716+ reason := "reason"
717+
718+ // Create test data for ObjectProperties
719+ createdByPolicy := true
720+ testUID := "test-uid-12345"
721+ testDiff := "test diff content"
722+ dryRunMatches := true
723+
724+ creationInfo := & policyv1.ObjectProperties {
725+ CreatedByPolicy : & createdByPolicy ,
726+ UID : testUID ,
727+ Diff : testDiff ,
728+ MatchesAfterDryRun : dryRunMatches ,
729+ }
730+
731+ relatedList := addRelatedObjects (
732+ compliant , scopedGVR , "ConfigurationPolicy" , namespace , []string {name }, reason , creationInfo ,
733+ )
734+ related := relatedList [0 ]
735+
736+ // Validate that the properties are correctly set
737+ assert .NotNil (t , related .Properties , "Properties should not be nil when creationInfo is provided" )
738+ assert .NotNil (t , related .Properties .CreatedByPolicy , "CreatedByPolicy should not be nil" )
739+ assert .Equal (t , createdByPolicy , * related .Properties .CreatedByPolicy )
740+ assert .Equal (t , testUID , related .Properties .UID )
741+ assert .Equal (t , testDiff , related .Properties .Diff )
742+ assert .Equal (t , dryRunMatches , related .Properties .MatchesAfterDryRun )
743+
744+ // add the same object and make sure the existing one is overwritten
745+ reason = "new"
746+ compliant = false
747+
748+ // Create new test data for ObjectProperties with different values
749+ newCreatedByPolicy := false
750+ newTestDiff := "updated diff content"
751+ newDryRunMatches := false
752+
753+ newCreationInfo := & policyv1.ObjectProperties {
754+ CreatedByPolicy : & newCreatedByPolicy ,
755+ UID : testUID ,
756+ Diff : newTestDiff ,
757+ MatchesAfterDryRun : newDryRunMatches ,
758+ }
759+
760+ relatedList = addRelatedObjects (
761+ compliant , scopedGVR , "ConfigurationPolicy" , namespace , []string {name }, reason , newCreationInfo )
762+ related = relatedList [0 ]
763+
764+ assert .Len (t , relatedList , 1 )
765+ assert .Equal (t , string (policyv1 .NonCompliant ), related .Compliant )
766+ assert .Equal (t , "new" , related .Reason )
767+
768+ // Validate that the properties were updated with new values
769+ assert .NotNil (t , related .Properties , "Properties should not be nil when newCreationInfo is provided" )
770+ assert .NotNil (t , related .Properties .CreatedByPolicy , "CreatedByPolicy should not be nil" )
771+ assert .Equal (t , newCreatedByPolicy , * related .Properties .CreatedByPolicy )
772+ assert .Equal (t , testUID , related .Properties .UID )
773+ assert .Equal (t , newTestDiff , related .Properties .Diff )
774+ assert .Equal (t , newDryRunMatches , related .Properties .MatchesAfterDryRun )
775+ }
776+
708777func TestCreateStatus (t * testing.T ) {
709778 testcases := []struct {
710779 testName string
@@ -1544,3 +1613,155 @@ func TestShouldHandleSingleKeyFalse(t *testing.T) {
15441613 assert .False (t , skip )
15451614 }
15461615}
1616+
1617+ // TestAlreadyEvaluated tests the core caching functionality for evaluated objects
1618+ func TestAlreadyEvaluated (t * testing.T ) {
1619+ // Create a test ConfigurationPolicy
1620+ policy := & policyv1.ConfigurationPolicy {
1621+ ObjectMeta : metav1.ObjectMeta {
1622+ Name : "test-policy" ,
1623+ Namespace : "default" ,
1624+ UID : types .UID ("test-policy-uid" ),
1625+ },
1626+ }
1627+
1628+ // Create a test unstructured object
1629+ testObj := & unstructured.Unstructured {
1630+ Object : map [string ]interface {}{
1631+ "apiVersion" : "v1" ,
1632+ "kind" : "ConfigMap" ,
1633+ "metadata" : map [string ]interface {}{
1634+ "name" : "test-configmap" ,
1635+ "namespace" : "default" ,
1636+ "uid" : "test-object-uid" ,
1637+ "resourceVersion" : "123" ,
1638+ },
1639+ },
1640+ }
1641+
1642+ // Create a reconciler with an empty cache
1643+ r := & ConfigurationPolicyReconciler {
1644+ processedPolicyCache : sync.Map {},
1645+ }
1646+
1647+ t .Run ("Test caching compliant=true" , func (t * testing.T ) {
1648+ // Call setEvaluatedObject with compliant=true
1649+ r .setEvaluatedObject (policy , testObj , true , "test message" )
1650+
1651+ // Verify the object was cached correctly
1652+ evaluated , compliant , msg := r .alreadyEvaluated (policy , testObj )
1653+
1654+ assert .True (t , evaluated , "Object should be marked as evaluated" )
1655+ assert .True (t , compliant , "Object should be marked as compliant" )
1656+ assert .Equal (t , "test message" , msg , "Message should match" )
1657+ })
1658+
1659+ t .Run ("Test caching compliant=false" , func (t * testing.T ) {
1660+ // Create a new policy and object to avoid cache interference
1661+ policy2 := & policyv1.ConfigurationPolicy {
1662+ ObjectMeta : metav1.ObjectMeta {
1663+ Name : "test-policy-2" ,
1664+ Namespace : "default" ,
1665+ UID : types .UID ("test-policy-uid-2" ),
1666+ },
1667+ }
1668+
1669+ testObj2 := & unstructured.Unstructured {
1670+ Object : map [string ]interface {}{
1671+ "apiVersion" : "v1" ,
1672+ "kind" : "ConfigMap" ,
1673+ "metadata" : map [string ]interface {}{
1674+ "name" : "test-configmap-2" ,
1675+ "namespace" : "default" ,
1676+ "uid" : "test-object-uid-2" ,
1677+ "resourceVersion" : "124" ,
1678+ },
1679+ },
1680+ }
1681+
1682+ // Call setEvaluatedObject with compliant=false
1683+ r .setEvaluatedObject (policy2 , testObj2 , false , "error message" )
1684+
1685+ // Verify the object was cached correctly
1686+ evaluated , compliant , msg := r .alreadyEvaluated (policy2 , testObj2 )
1687+
1688+ assert .True (t , evaluated , "Object should be marked as evaluated" )
1689+ assert .False (t , compliant , "Object should be marked as non-compliant" )
1690+ assert .Equal (t , "error message" , msg , "Message should match" )
1691+ })
1692+
1693+ t .Run ("Test not cached object" , func (t * testing.T ) {
1694+ // Create a completely new policy and object
1695+ policy3 := & policyv1.ConfigurationPolicy {
1696+ ObjectMeta : metav1.ObjectMeta {
1697+ Name : "test-policy-3" ,
1698+ Namespace : "default" ,
1699+ UID : types .UID ("test-policy-uid-3" ),
1700+ },
1701+ }
1702+
1703+ testObj3 := & unstructured.Unstructured {
1704+ Object : map [string ]interface {}{
1705+ "apiVersion" : "v1" ,
1706+ "kind" : "ConfigMap" ,
1707+ "metadata" : map [string ]interface {}{
1708+ "name" : "test-configmap-3" ,
1709+ "namespace" : "default" ,
1710+ "uid" : "test-object-uid-3" ,
1711+ "resourceVersion" : "125" ,
1712+ },
1713+ },
1714+ }
1715+
1716+ // Call alreadyEvaluated without caching first
1717+ evaluated , compliant , msg := r .alreadyEvaluated (policy3 , testObj3 )
1718+
1719+ assert .False (t , evaluated , "Object should not be marked as evaluated" )
1720+ assert .False (t , compliant , "Object should be marked as non-compliant" )
1721+ assert .Empty (t , msg , "Message should be empty" )
1722+ })
1723+
1724+ t .Run ("Test resource version change invalidates cache" , func (t * testing.T ) {
1725+ // Use the same policy but change the resource version
1726+ testObjNewVersion := & unstructured.Unstructured {
1727+ Object : map [string ]interface {}{
1728+ "apiVersion" : "v1" ,
1729+ "kind" : "ConfigMap" ,
1730+ "metadata" : map [string ]interface {}{
1731+ "name" : "test-configmap" ,
1732+ "namespace" : "default" ,
1733+ "uid" : "test-object-uid" ,
1734+ "resourceVersion" : "456" , // Different resource version
1735+ },
1736+ },
1737+ }
1738+
1739+ // Call alreadyEvaluated - should return false due to different resource version
1740+ // but the cached values from the previous evaluation should still be returned
1741+ evaluated , compliant , msg := r .alreadyEvaluated (policy , testObjNewVersion )
1742+
1743+ assert .False (t , evaluated , "Object should not be marked as evaluated due to different resource version" )
1744+ assert .True (t , compliant , "Should return the cached compliance state from previous evaluation" )
1745+ assert .Equal (t , "test message" , msg , "Should return the cached message from previous evaluation" )
1746+ })
1747+
1748+ t .Run ("Test nil inputs" , func (t * testing.T ) {
1749+ // Test with nil policy
1750+ evaluated , compliant , msg := r .alreadyEvaluated (nil , testObj )
1751+ assert .False (t , evaluated )
1752+ assert .False (t , compliant )
1753+ assert .Empty (t , msg )
1754+
1755+ // Test with nil object
1756+ evaluated , compliant , msg = r .alreadyEvaluated (policy , nil )
1757+ assert .False (t , evaluated )
1758+ assert .False (t , compliant )
1759+ assert .Empty (t , msg )
1760+
1761+ // Test with both nil
1762+ evaluated , compliant , msg = r .alreadyEvaluated (nil , nil )
1763+ assert .False (t , evaluated )
1764+ assert .False (t , compliant )
1765+ assert .Empty (t , msg )
1766+ })
1767+ }
0 commit comments