1515package agentendpoint
1616
1717import (
18+ "context"
19+ "errors"
1820 "reflect"
1921 "regexp"
2022 "strings"
2123 "testing"
24+ "time"
2225
26+ "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb"
2327 "github.com/GoogleCloudPlatform/osconfig/ospatch"
28+ "github.com/GoogleCloudPlatform/osconfig/packages"
29+ "github.com/GoogleCloudPlatform/osconfig/util/utiltest"
2430)
2531
2632func TestExcludeConversion (t * testing.T ) {
2733 regex , _ := regexp .Compile ("PackageName" )
2834 emptyRegex , _ := regexp .Compile ("" )
35+ _ , regexpErr := regexp .Compile ("[a-z" )
2936
3037 tests := []struct {
31- name string
32- input []string
33- want []* ospatch.Exclude
38+ name string
39+ input []string
40+ want []* ospatch.Exclude
41+ wantErr error
3442 }{
35- {name : "StrictStringConversion" , input : []string {"PackageName" }, want : CreateStringExcludes ("PackageName" )},
36- {name : "MultipleStringConversion" , input : []string {"PackageName1" , "PackageName2" }, want : CreateStringExcludes ("PackageName1" , "PackageName2" )},
37- {name : "RegexConversion" , input : []string {"/PackageName/" }, want : []* ospatch.Exclude {ospatch .CreateRegexExclude (regex )}},
38- {name : "CornerCaseRegex" , input : []string {"//" }, want : []* ospatch.Exclude {ospatch .CreateRegexExclude (emptyRegex )}},
39- {name : "CornerCaseStrictString" , input : []string {"/" }, want : CreateStringExcludes ("/" )},
40- {name : "CornerCaseEmptyString" , input : []string {"" }, want : CreateStringExcludes ("" )},
43+ {name : "Single package name, want one string exclude" , input : []string {"PackageName" }, want : createStringExcludes ("PackageName" )},
44+ {name : "Multiple package names, want multiple string excludes" , input : []string {"PackageName1" , "PackageName2" }, want : createStringExcludes ("PackageName1" , "PackageName2" )},
45+ {name : "Slash-wrapped value, want regex exclude" , input : []string {"/PackageName/" }, want : []* ospatch.Exclude {ospatch .CreateRegexExclude (regex )}},
46+ {name : "Empty regex //, want empty regex exclude" , input : []string {"//" }, want : []* ospatch.Exclude {ospatch .CreateRegexExclude (emptyRegex )}},
47+ {name : "Single slash, want string exclude" , input : []string {"/" }, want : createStringExcludes ("/" )},
48+ {name : "Empty string, want string exclude" , input : []string {"" }, want : createStringExcludes ("" )},
49+ {name : "Invalid regex, want regex compile error" , input : []string {"/[a-z/" }, wantErr : regexpErr },
4150 }
4251
4352 for _ , tt := range tests {
4453 t .Run (tt .name , func (t * testing.T ) {
4554 excludes , err := convertInputToExcludes (tt .input )
46- if err != nil {
47- t .Errorf ("err = %v, want %v" , err , nil )
48- }
55+
4956 if ! reflect .DeepEqual (excludes , tt .want ) {
5057 t .Errorf ("convertInputToExcludes() = %s, want = %s" , toString (excludes ), toString (tt .want ))
5158 }
59+ utiltest .AssertErrorMatch (t , err , tt .wantErr )
60+ })
61+ }
62+ }
63+
64+ func TestRunUpdates (t * testing.T ) {
65+ utiltest .OverrideVariable (t , & retryPeriod , 1 * time .Millisecond )
66+
67+ mockAptSuccess := func (ctx context.Context , opts ... ospatch.AptGetUpgradeOption ) error { return nil }
68+ mockYumSuccess := func (ctx context.Context , opts ... ospatch.YumUpdateOption ) error { return nil }
69+ mockZypperSuccess := func (ctx context.Context , opts ... ospatch.ZypperPatchOption ) error { return nil }
70+ mockAptErr := func (ctx context.Context , opts ... ospatch.AptGetUpgradeOption ) error { return errors .New ("apt err" ) }
71+ mockYumErr := func (ctx context.Context , opts ... ospatch.YumUpdateOption ) error { return errors .New ("yum err" ) }
72+ mockZypperErr := func (ctx context.Context , opts ... ospatch.ZypperPatchOption ) error { return errors .New ("zypper err" ) }
73+ _ , regexpErr := regexp .Compile ("[a-z" )
74+
75+ tests := []struct {
76+ name string
77+ setup func (t * testing.T )
78+ taskConfig * agentendpointpb.PatchConfig
79+ wantErr error
80+ }{
81+ {
82+ name : "No package managers detected, want no patch operations attempted and no error" ,
83+ setup : func (t * testing.T ) {
84+ disableAllPackageManagers (t )
85+ },
86+ taskConfig : & agentendpointpb.PatchConfig {},
87+ wantErr : nil ,
88+ },
89+ {
90+ name : "Apt available, want apt-get dist-upgrade attempted and no error" ,
91+ setup : func (t * testing.T ) {
92+ disableAllPackageManagers (t )
93+ enableApt (t , mockAptSuccess )
94+ },
95+ taskConfig : & agentendpointpb.PatchConfig {
96+ Apt : & agentendpointpb.AptSettings {Type : agentendpointpb .AptSettings_DIST },
97+ },
98+ wantErr : nil ,
99+ },
100+ {
101+ name : "Apt available with invalid regex in excludes, want regex compile error and no upgrade attempted" ,
102+ setup : func (t * testing.T ) {
103+ disableAllPackageManagers (t )
104+ enableApt (t , nil )
105+ },
106+ taskConfig : & agentendpointpb.PatchConfig {
107+ Apt : & agentendpointpb.AptSettings {Excludes : []string {"/[a-z/" }},
108+ },
109+ wantErr : regexpErr ,
110+ },
111+ {
112+ name : "Yum available, want yum update attempted and no error" ,
113+ setup : func (t * testing.T ) {
114+ disableAllPackageManagers (t )
115+ enableYum (t , mockYumSuccess )
116+ },
117+ taskConfig : & agentendpointpb.PatchConfig {
118+ Yum : & agentendpointpb.YumSettings {
119+ Security : true ,
120+ Minimal : true ,
121+ },
122+ },
123+ wantErr : nil ,
124+ },
125+ {
126+ name : "Zypper available, want zypper patch attempted and no error" ,
127+ setup : func (t * testing.T ) {
128+ disableAllPackageManagers (t )
129+ enableZypper (t , mockZypperSuccess )
130+ },
131+ taskConfig : & agentendpointpb.PatchConfig {
132+ Zypper : & agentendpointpb.ZypperSettings {
133+ WithUpdate : true ,
134+ WithOptional : true ,
135+ },
136+ },
137+ wantErr : nil ,
138+ },
139+ {
140+ name : "Yum available with invalid regex in excludes, want regex compile error and no update attempted" ,
141+ setup : func (t * testing.T ) {
142+ disableAllPackageManagers (t )
143+ enableYum (t , nil )
144+ },
145+ taskConfig : & agentendpointpb.PatchConfig {
146+ Yum : & agentendpointpb.YumSettings {Excludes : []string {"/[a-z/" }},
147+ },
148+ wantErr : regexpErr ,
149+ },
150+ {
151+ name : "Zypper available with invalid regex in excludes, want regex compile error and no patch attempted" ,
152+ setup : func (t * testing.T ) {
153+ disableAllPackageManagers (t )
154+ enableZypper (t , nil )
155+ },
156+ taskConfig : & agentendpointpb.PatchConfig {
157+ Zypper : & agentendpointpb.ZypperSettings {Excludes : []string {"/[a-z/" }},
158+ },
159+ wantErr : regexpErr ,
160+ },
161+ {
162+ name : "Yum available and yum update returns error, want that error returned" ,
163+ setup : func (t * testing.T ) {
164+ disableAllPackageManagers (t )
165+ enableYum (t , mockYumErr )
166+ },
167+ taskConfig : & agentendpointpb.PatchConfig {
168+ Yum : & agentendpointpb.YumSettings {},
169+ },
170+ wantErr : errors .New ("yum err" ),
171+ },
172+ {
173+ name : "All package managers available and each fails, want all three errors aggregated" ,
174+ setup : func (t * testing.T ) {
175+ disableAllPackageManagers (t )
176+ enableApt (t , mockAptErr )
177+ enableYum (t , mockYumErr )
178+ enableZypper (t , mockZypperErr )
179+ },
180+ taskConfig : & agentendpointpb.PatchConfig {
181+ Apt : & agentendpointpb.AptSettings {},
182+ Yum : & agentendpointpb.YumSettings {},
183+ Zypper : & agentendpointpb.ZypperSettings {},
184+ },
185+ wantErr : errors .New ("apt err,\n yum err,\n zypper err" ),
186+ },
187+ }
188+
189+ for _ , tt := range tests {
190+ t .Run (tt .name , func (t * testing.T ) {
191+ tt .setup (t )
192+ task := initializePatchTask (tt .taskConfig )
193+
194+ err := task .runUpdates (context .Background ())
195+ utiltest .AssertErrorMatch (t , err , tt .wantErr )
52196 })
53197 }
54198}
55199
200+ func initializePatchTask (config * agentendpointpb.PatchConfig ) * patchTask {
201+ return & patchTask {
202+ Task : & applyPatchesTask {
203+ ApplyPatchesTask : & agentendpointpb.ApplyPatchesTask {
204+ PatchConfig : config ,
205+ },
206+ },
207+ }
208+ }
209+
210+ func disableAllPackageManagers (t * testing.T ) {
211+ t .Helper ()
212+ utiltest .OverrideVariable (t , & packages .DpkgQueryExists , false )
213+ utiltest .OverrideVariable (t , & packages .YumExists , false )
214+ utiltest .OverrideVariable (t , & packages .RPMQueryExists , false )
215+ utiltest .OverrideVariable (t , & packages .ZypperExists , false )
216+ }
217+
218+ func enableApt (t * testing.T , run func (ctx context.Context , opts ... ospatch.AptGetUpgradeOption ) error ) {
219+ t .Helper ()
220+ utiltest .OverrideVariable (t , & packages .AptExists , true )
221+ utiltest .OverrideVariable (t , & packages .DpkgQueryExists , true )
222+ if run != nil {
223+ utiltest .OverrideVariable (t , & runAptGetUpgrade , run )
224+ }
225+ }
226+
227+ func enableYum (t * testing.T , run func (ctx context.Context , opts ... ospatch.YumUpdateOption ) error ) {
228+ t .Helper ()
229+ utiltest .OverrideVariable (t , & packages .YumExists , true )
230+ utiltest .OverrideVariable (t , & packages .RPMQueryExists , true )
231+ if run != nil {
232+ utiltest .OverrideVariable (t , & runYumUpdate , run )
233+ }
234+ }
235+
236+ func enableZypper (t * testing.T , run func (ctx context.Context , opts ... ospatch.ZypperPatchOption ) error ) {
237+ t .Helper ()
238+ utiltest .OverrideVariable (t , & packages .ZypperExists , true )
239+ utiltest .OverrideVariable (t , & packages .RPMQueryExists , true )
240+ if run != nil {
241+ utiltest .OverrideVariable (t , & runZypperPatch , run )
242+ }
243+ }
244+
56245func toString (excludes []* ospatch.Exclude ) string {
57246 results := make ([]string , len (excludes ))
58247 for i , exc := range excludes {
@@ -62,7 +251,7 @@ func toString(excludes []*ospatch.Exclude) string {
62251 return strings .Join (results , "," )
63252}
64253
65- func CreateStringExcludes (pkgs ... string ) []* ospatch.Exclude {
254+ func createStringExcludes (pkgs ... string ) []* ospatch.Exclude {
66255 excludes := make ([]* ospatch.Exclude , len (pkgs ))
67256 for i := 0 ; i < len (pkgs ); i ++ {
68257 pkg := pkgs [i ]
0 commit comments