@@ -29,12 +29,10 @@ import (
29
29
"github.com/coreos/coreos-assembler/mantle/kola/register"
30
30
"github.com/coreos/coreos-assembler/mantle/platform"
31
31
"github.com/coreos/coreos-assembler/mantle/platform/conf"
32
- "github.com/coreos/ignition/v2/config/v3_2/types"
33
32
"github.com/coreos/coreos-assembler/mantle/util"
33
+ "github.com/coreos/ignition/v2/config/v3_2/types"
34
34
)
35
35
36
- var console bool
37
-
38
36
func init () {
39
37
register .RegisterTest (& register.Test {
40
38
Name : "coreos.ignition.failure" ,
@@ -78,42 +76,60 @@ func runDualBootfsIgnitionFailure(c cluster.TestCluster) {
78
76
}
79
77
}
80
78
81
- func ignitionFailure (c cluster.TestCluster ) error {
82
- // We can't create files in / due to the immutable bit OSTree creates, so
83
- // this is a convenient way to test Ignition failure.
84
- failConfig , err := conf .EmptyIgnition ().Render (conf .FailWarnings )
79
+ // Read file and verify if it contains a pattern
80
+ // 1. Read file, make sure it exists
81
+ // 2. regex for pattern
82
+ func fileHasPattern (tempLogFilePath string , searchPattern string ) (bool , error ) {
83
+ file , err := os .ReadFile (tempLogFilePath )
85
84
if err != nil {
86
- return errors . Wrapf ( err , "creating empty config" )
85
+ return false , err
87
86
}
88
- failConfig .AddFile ("/notwritable.txt" , "Hello world" , 0644 )
89
-
90
- builder := platform .NewQemuBuilder () // platform.Manhole()
91
- if err != nil {
92
- return err
87
+ // File exists but it's empty
88
+ if len (file ) == 0 {
89
+ return false , nil
93
90
}
94
- builder .MemoryMiB = 1024
95
- builder .Firmware = kola .QEMUOptions .Firmware
91
+ // File has content, but the pattern is not present
92
+ match := regexp .MustCompile (searchPattern ).Match (file )
93
+ if match {
94
+ // Pattern found
95
+ return true , nil
96
+ }
97
+ // Pattern not found
98
+ return false , nil
99
+ }
100
+
101
+ // Start the VM, take string and grep for it in the temporary console logs
102
+ func verifyError (builder * platform.QemuBuilder , searchPattern string ) error {
96
103
inst , err := builder .Exec ()
97
104
if err != nil {
98
105
return err
99
106
}
100
107
defer inst .Destroy ()
101
-
102
108
ctx , cancel := context .WithTimeout (context .Background (), 2 * time .Minute )
109
+
103
110
defer cancel ()
104
111
105
112
errchan := make (chan error )
106
113
go func () {
107
- err := inst .WaitAll (ctx )
108
- if err == nil {
109
- err = fmt .Errorf ("Ignition unexpectedly succeeded" )
110
- } else if err == platform .ErrInitramfsEmergency {
111
- // The expected case
112
- err = nil
114
+ resultingError := inst .WaitAll (ctx )
115
+ if resultingError == nil {
116
+ resultingError = fmt .Errorf ("ignition unexpectedly succeeded" )
117
+ } else if resultingError == platform .ErrInitramfsEmergency {
118
+ // Expectred initramfs failure, checking the console file to insure
119
+ // that coreos.ignition.failure failed
120
+ found , err := fileHasPattern (builder .ConsoleFile , searchPattern )
121
+ if err != nil {
122
+ resultingError = errors .Wrapf (err , "failed to find pattern '%s' in file '%s'" , searchPattern , builder .ConsoleFile )
123
+ } else if ! found {
124
+ resultingError = fmt .Errorf ("regex match NOT found" )
125
+ } else {
126
+ // The expected case
127
+ resultingError = nil
128
+ }
113
129
} else {
114
- err = errors .Wrapf (err , "expected initramfs emergency.target error" )
130
+ resultingError = errors .Wrapf (resultingError , "expected initramfs emergency.target error" )
115
131
}
116
- errchan <- err
132
+ errchan <- resultingError
117
133
}()
118
134
119
135
select {
@@ -130,16 +146,55 @@ func ignitionFailure(c cluster.TestCluster) error {
130
146
}
131
147
}
132
148
133
- // Verify that there is only one boot filesystem attached to the device
134
- func dualBootfsFailure (c cluster.TestCluster ) error {
149
+ func ignitionFailure (c cluster.TestCluster ) error {
150
+ // We can't create files in / due to the immutable bit OSTree creates, so
151
+ // this is a convenient way to test Ignition failure.
152
+ failConfig , err := conf .EmptyIgnition ().Render (conf .FailWarnings )
153
+ if err != nil {
154
+ return errors .Wrapf (err , "creating empty config" )
155
+ }
156
+ failConfig .AddFile ("/notwritable.txt" , "Hello world" , 0644 )
157
+
135
158
builder := platform .NewQemuBuilder ()
136
159
137
- consoleFile , err := builder .TempFile ("console.log" )
160
+ // Create a temporary log file
161
+ ConsoleFile , err := builder .TempFile ("console.log" )
162
+ if err != nil {
163
+ return err
164
+ }
165
+ tempLogFilePath := ConsoleFile .Name ()
166
+ // Instruct builder to use it
167
+ builder .ConsoleFile = tempLogFilePath
168
+ defer builder .Close ()
169
+ builder .SetConfig (failConfig )
170
+ err = builder .AddBootDisk (& platform.Disk {
171
+ BackingFile : kola .QEMUOptions .DiskImage ,
172
+ })
138
173
if err != nil {
139
174
return err
140
175
}
141
- builder .ConsoleFile = consoleFile .Name ()
142
176
177
+ builder .MemoryMiB = 1024
178
+ builder .Firmware = kola .QEMUOptions .Firmware
179
+
180
+ searchPattern := "error creating /sysroot/notwritable.txt"
181
+ if err := verifyError (builder , searchPattern ); err != nil {
182
+ return err
183
+ }
184
+ return nil
185
+ }
186
+
187
+ // Verify that there is only one boot filesystem attached to the device
188
+ func dualBootfsFailure (c cluster.TestCluster ) error {
189
+ builder := platform .NewQemuBuilder ()
190
+ // Create a temporary log file
191
+ ConsoleFile , err := builder .TempFile ("console.log" )
192
+ if err != nil {
193
+ return err
194
+ }
195
+ tempLogFilePath := ConsoleFile .Name ()
196
+ // Instruct builder to use it
197
+ builder .ConsoleFile = tempLogFilePath
143
198
// get current path and create tmp dir
144
199
fakeBootFile , err := builder .TempFile ("fakeBoot" )
145
200
if err != nil {
@@ -174,85 +229,40 @@ func dualBootfsFailure(c cluster.TestCluster) error {
174
229
}
175
230
builder .MemoryMiB = 1024
176
231
builder .Firmware = kola .QEMUOptions .Firmware
177
- inst , err := builder .Exec ()
178
- if err != nil {
179
- return err
180
- } // platform.Manhole()
181
- defer inst .Destroy ()
182
232
183
- ctx , cancel := context .WithTimeout (context .Background (), 2 * time .Minute )
184
- defer cancel ()
185
-
186
- errchan := make (chan error )
187
- go func () {
188
- resultingError := inst .WaitAll (ctx )
189
-
190
- if resultingError == nil {
191
- resultingError = fmt .Errorf ("bootfs unexpectedly succeeded" )
192
- } else if resultingError == platform .ErrInitramfsEmergency {
193
- // Expectred initramfs failure, checking the console file to insure
194
- // that coreos-unique-boot.service failed
195
- b , err := os .ReadFile (builder .ConsoleFile )
196
- if err != nil {
197
- panic (err )
198
- }
199
- isExist , err := regexp .Match ("Error: System has 2 devices with a filesystem labeled 'boot'" , b )
200
- if err != nil {
201
- panic (err )
202
- }
203
- if isExist {
204
- // The expected case
205
- resultingError = nil
206
- } else {
207
- resultingError = errors .Wrapf (err , "expected coreos-unique-boot.service to fail" )
208
- }
209
- } else {
210
- resultingError = errors .Wrapf (err , "expected initramfs emergency.target error" )
211
- }
212
- errchan <- resultingError
213
- }()
214
-
215
- select {
216
- case <- ctx .Done ():
217
- if err := inst .Kill (); err != nil {
218
- return errors .Wrapf (err , "failed to kill the vm instance" )
219
- }
220
- return errors .Wrapf (ctx .Err (), "timed out waiting for initramfs error" )
221
- case err := <- errchan :
222
- if err != nil {
223
- return err
224
- }
225
- return nil
233
+ searchRegexString := "Error: System has 2 devices with a filesystem labeled 'boot'"
234
+ if err := verifyError (builder , searchRegexString ); err != nil {
235
+ return err
226
236
}
237
+ return nil
227
238
}
228
239
229
240
// Use ignition config to create a second bootfs
230
241
// 1 - produce an ignition file that format a disk with a"boot" label.
231
242
// 2 - boot the VM with the ignition file and an extra disk.
232
- // 3 - observe the failure
243
+ // 3 - observe the failure
233
244
func dualBootfsIgnitionFailure (c cluster.TestCluster ) error {
234
245
builder := platform .NewQemuBuilder ()
235
- // inserting log file for troubleshooting
236
- // file located in coreos-assembler directory
237
-
238
- // consoleFile, err := builder.TempFile("console.log")
239
- // if err != nil {
240
- // return err
241
- // }
242
- //builder.ConsoleFile = consoleFile.Name()
243
- builder .ConsoleFile = "console.txt"
244
246
247
+ // Create a temporary log file
248
+ ConsoleFile , err := builder .TempFile ("console.log" )
249
+ if err != nil {
250
+ return err
251
+ }
252
+ tempLogFilePath := ConsoleFile .Name ()
253
+ // Instruct builder to use it
254
+ builder .ConsoleFile = tempLogFilePath
245
255
failConfig , err := conf .EmptyIgnition ().Render (conf .FailWarnings )
246
256
if err != nil {
247
257
return errors .Wrapf (err , "creating empty config" )
248
258
}
249
259
250
- // Craft an ingniton file that format a partition
251
- formaterConfig := types.Config {
260
+ // Craft an Ingniton file that formats a partition
261
+ formaterConfig := types.Config {
252
262
Ignition : types.Ignition {
253
263
Version : "3.2.0" ,
254
264
},
255
- Storage : types.Storage {
265
+ Storage : types.Storage {
256
266
Filesystems : []types.Filesystem {
257
267
{
258
268
Device : "/dev/disk/by-id/virtio-extra-boot" ,
@@ -281,54 +291,10 @@ func dualBootfsIgnitionFailure(c cluster.TestCluster) error {
281
291
282
292
builder .MemoryMiB = 1024
283
293
builder .Firmware = kola .QEMUOptions .Firmware
284
- inst , err := builder .Exec ()
285
- if err != nil {
286
- return err
287
- }
288
- defer inst .Destroy ()
289
294
290
- ctx , cancel := context .WithTimeout (context .Background (), 2 * time .Minute )
291
- defer cancel ()
292
-
293
- errchan := make (chan error )
294
- go func () {
295
- resultingError := inst .WaitAll (ctx )
296
-
297
- if resultingError == nil {
298
- resultingError = fmt .Errorf ("bootfs unexpectedly succeeded" )
299
- } else if resultingError == platform .ErrInitramfsEmergency {
300
- // Expectred initramfs failure, checking the console file to insure
301
- // that coreos-unique-boot.service failed
302
- b , err := os .ReadFile (builder .ConsoleFile )
303
- if err != nil {
304
- panic (err )
305
- }
306
- isExist , err := regexp .Match ("Error: System has 2 devices with a filesystem labeled 'boot'" , b )
307
- if err != nil {
308
- panic (err )
309
- }
310
- if isExist {
311
- // The expected case
312
- resultingError = nil
313
- } else {
314
- resultingError = errors .Wrapf (err , "expected coreos-unique-boot.service to fail" )
315
- }
316
- } else {
317
- resultingError = errors .Wrapf (err , "expected initramfs emergency.target error" )
318
- }
319
- errchan <- resultingError
320
- }()
321
-
322
- select {
323
- case <- ctx .Done ():
324
- if err := inst .Kill (); err != nil {
325
- return errors .Wrapf (err , "failed to kill the vm instance" )
326
- }
327
- return errors .Wrapf (ctx .Err (), "timed out waiting for initramfs error" )
328
- case err := <- errchan :
329
- if err != nil {
330
- return err
331
- }
332
- return nil
295
+ searchRegexString := "Error: System has 2 devices with a filesystem labeled 'boot'"
296
+ if err := verifyError (builder , searchRegexString ); err != nil {
297
+ return err
333
298
}
299
+ return nil
334
300
}
0 commit comments