@@ -10,17 +10,21 @@ import (
10
10
"testing"
11
11
12
12
"github.com/argoproj/gitops-engine/pkg/diff/testdata"
13
- "github.com/argoproj/gitops-engine/pkg/utils/kube/scheme "
13
+ openapi_v2 "github.com/google/gnostic/openapiv2 "
14
14
"github.com/stretchr/testify/assert"
15
15
"github.com/stretchr/testify/require"
16
+ "google.golang.org/protobuf/proto"
16
17
appsv1 "k8s.io/api/apps/v1"
17
18
corev1 "k8s.io/api/core/v1"
18
19
v1 "k8s.io/api/core/v1"
19
20
"k8s.io/apimachinery/pkg/api/equality"
20
21
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21
22
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22
23
"k8s.io/apimachinery/pkg/runtime"
24
+ "k8s.io/apimachinery/pkg/util/intstr"
25
+ "k8s.io/apimachinery/pkg/util/managedfields"
23
26
"k8s.io/klog/v2/klogr"
27
+ openapiproto "k8s.io/kube-openapi/pkg/util/proto"
24
28
"sigs.k8s.io/yaml"
25
29
)
26
30
@@ -747,39 +751,68 @@ func TestUnsortedEndpoints(t *testing.T) {
747
751
}
748
752
}
749
753
754
+ func buildGVKParser (t * testing.T ) * managedfields.GvkParser {
755
+ document := & openapi_v2.Document {}
756
+ err := proto .Unmarshal (testdata .OpenAPIV2Doc , document )
757
+ if err != nil {
758
+ t .Fatalf ("error unmarshaling openapi doc: %s" , err )
759
+ }
760
+ models , err := openapiproto .NewOpenAPIData (document )
761
+ if err != nil {
762
+ t .Fatalf ("error building openapi data: %s" , err )
763
+ }
764
+
765
+ gvkParser , err := managedfields .NewGVKParser (models , false )
766
+ if err != nil {
767
+ t .Fatalf ("error building gvkParser: %s" , err )
768
+ }
769
+ return gvkParser
770
+ }
771
+
750
772
func TestStructuredMergeDiff (t * testing.T ) {
751
- parser := scheme .StaticParser ()
752
- svcParseType := parser .Type ("io.k8s.api.core.v1.Service" )
753
- manager := "argocd-controller"
773
+ buildParams := func (live , config * unstructured.Unstructured ) * SMDParams {
774
+ gvkParser := buildGVKParser (t )
775
+ manager := "argocd-controller"
776
+ return & SMDParams {
777
+ config : config ,
778
+ live : live ,
779
+ gvkParser : gvkParser ,
780
+ manager : manager ,
781
+ }
782
+ }
754
783
755
784
t .Run ("will apply default values" , func (t * testing.T ) {
756
785
// given
786
+ t .Parallel ()
757
787
liveState := StrToUnstructured (testdata .ServiceLiveYAML )
758
788
desiredState := StrToUnstructured (testdata .ServiceConfigYAML )
789
+ params := buildParams (liveState , desiredState )
759
790
760
791
// when
761
- result , err := structuredMergeDiff (desiredState , liveState , & svcParseType , manager )
792
+ result , err := structuredMergeDiff (params )
762
793
763
794
// then
764
795
require .NoError (t , err )
765
796
assert .NotNil (t , result )
766
- assert .False (t , result .Modified )
797
+ assert .True (t , result .Modified )
767
798
predictedSVC := YamlToSvc (t , result .PredictedLive )
768
799
liveSVC := YamlToSvc (t , result .NormalizedLive )
769
- assert .NotNil (t , predictedSVC .Spec .InternalTrafficPolicy )
770
- assert .NotNil (t , liveSVC .Spec .InternalTrafficPolicy )
800
+ require .NotNil (t , predictedSVC .Spec .InternalTrafficPolicy )
801
+ require .NotNil (t , liveSVC .Spec .InternalTrafficPolicy )
771
802
assert .Equal (t , "Cluster" , string (* predictedSVC .Spec .InternalTrafficPolicy ))
772
803
assert .Equal (t , "Cluster" , string (* liveSVC .Spec .InternalTrafficPolicy ))
773
804
assert .Empty (t , predictedSVC .Annotations [AnnotationLastAppliedConfig ])
774
805
assert .Empty (t , liveSVC .Annotations [AnnotationLastAppliedConfig ])
775
806
})
776
807
t .Run ("will remove entries in list" , func (t * testing.T ) {
777
808
// given
809
+ t .Parallel ()
778
810
liveState := StrToUnstructured (testdata .ServiceLiveYAML )
779
811
desiredState := StrToUnstructured (testdata .ServiceConfigWith2Ports )
812
+ params := buildParams (liveState , desiredState )
780
813
781
814
// when
782
- result , err := structuredMergeDiff (desiredState , liveState , & svcParseType , manager )
815
+ result , err := structuredMergeDiff (params )
783
816
784
817
// then
785
818
require .NoError (t , err )
@@ -790,11 +823,13 @@ func TestStructuredMergeDiff(t *testing.T) {
790
823
})
791
824
t .Run ("will remove previously added fields not present in desired state" , func (t * testing.T ) {
792
825
// given
826
+ t .Parallel ()
793
827
liveState := StrToUnstructured (testdata .LiveServiceWithTypeYAML )
794
828
desiredState := StrToUnstructured (testdata .ServiceConfigYAML )
829
+ params := buildParams (liveState , desiredState )
795
830
796
831
// when
797
- result , err := structuredMergeDiff (desiredState , liveState , & svcParseType , manager )
832
+ result , err := structuredMergeDiff (params )
798
833
799
834
// then
800
835
require .NoError (t , err )
@@ -805,11 +840,13 @@ func TestStructuredMergeDiff(t *testing.T) {
805
840
})
806
841
t .Run ("will apply service with multiple ports" , func (t * testing.T ) {
807
842
// given
843
+ t .Parallel ()
808
844
liveState := StrToUnstructured (testdata .ServiceLiveYAML )
809
845
desiredState := StrToUnstructured (testdata .ServiceConfigWithSamePortsYAML )
846
+ params := buildParams (liveState , desiredState )
810
847
811
848
// when
812
- result , err := structuredMergeDiff (desiredState , liveState , & svcParseType , manager )
849
+ result , err := structuredMergeDiff (params )
813
850
814
851
// then
815
852
require .NoError (t , err )
@@ -818,6 +855,36 @@ func TestStructuredMergeDiff(t *testing.T) {
818
855
svc := YamlToSvc (t , result .PredictedLive )
819
856
assert .Len (t , svc .Spec .Ports , 5 )
820
857
})
858
+ t .Run ("will apply deployment defaults correctly" , func (t * testing.T ) {
859
+ // given
860
+ t .Parallel ()
861
+ liveState := StrToUnstructured (testdata .DeploymentLiveYAML )
862
+ desiredState := StrToUnstructured (testdata .DeploymentConfigYAML )
863
+ params := buildParams (liveState , desiredState )
864
+
865
+ // when
866
+ result , err := structuredMergeDiff (params )
867
+
868
+ // then
869
+ require .NoError (t , err )
870
+ assert .NotNil (t , result )
871
+ assert .False (t , result .Modified )
872
+ deploy := YamlToDeploy (t , result .PredictedLive )
873
+ assert .Len (t , deploy .Spec .Template .Spec .Containers , 1 )
874
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Requests .Cpu ().String ())
875
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Requests .Memory ().String ())
876
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Requests .Storage ().String ())
877
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Limits .Cpu ().String ())
878
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Limits .Memory ().String ())
879
+ assert .Equal (t , "0" , deploy .Spec .Template .Spec .Containers [0 ].Resources .Limits .Storage ().String ())
880
+ require .NotNil (t , deploy .Spec .Strategy .RollingUpdate )
881
+ expectedMaxSurge := & intstr.IntOrString {
882
+ Type : intstr .String ,
883
+ StrVal : "25%" ,
884
+ }
885
+ assert .Equal (t , expectedMaxSurge , deploy .Spec .Strategy .RollingUpdate .MaxSurge )
886
+ assert .Equal (t , "ClusterFirst" , string (deploy .Spec .Template .Spec .DNSPolicy ))
887
+ })
821
888
}
822
889
823
890
func createSecret (data map [string ]string ) * unstructured.Unstructured {
@@ -1078,6 +1145,16 @@ func YamlToSvc(t *testing.T, y []byte) *corev1.Service {
1078
1145
return & svc
1079
1146
}
1080
1147
1148
+ func YamlToDeploy (t * testing.T , y []byte ) * appsv1.Deployment {
1149
+ t .Helper ()
1150
+ deploy := appsv1.Deployment {}
1151
+ err := yaml .Unmarshal (y , & deploy )
1152
+ if err != nil {
1153
+ t .Fatalf ("error unmarshaling deployment bytes: %s" , err )
1154
+ }
1155
+ return & deploy
1156
+ }
1157
+
1081
1158
func StrToUnstructured (yamlStr string ) * unstructured.Unstructured {
1082
1159
obj := make (map [string ]interface {})
1083
1160
err := yaml .Unmarshal ([]byte (yamlStr ), & obj )
0 commit comments