Skip to content

Commit f16dc32

Browse files
committed
tests: add ostree.sync test
Add test for https://issues.redhat.com/browse/OCPBUGS-15917, to verify ostree can sync the filesystem with the disconnected network volume(NFS). As we do not have ceph for testing, according to the suggestion from Colin and Joseph: `use something like NFS, we should in theory see the same error if we disconnected the NFS volume and we could not sync the filesystem.` Coworked with JB.
1 parent 09868d1 commit f16dc32

File tree

1 file changed

+252
-0
lines changed

1 file changed

+252
-0
lines changed

mantle/kola/tests/ostree/sync.go

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Copyright 2015 CoreOS, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package ostree
16+
17+
import (
18+
"fmt"
19+
"strings"
20+
"time"
21+
22+
"github.com/coreos/coreos-assembler/mantle/kola"
23+
"github.com/coreos/coreos-assembler/mantle/kola/cluster"
24+
"github.com/coreos/coreos-assembler/mantle/kola/register"
25+
"github.com/coreos/coreos-assembler/mantle/platform"
26+
"github.com/coreos/coreos-assembler/mantle/platform/conf"
27+
"github.com/coreos/coreos-assembler/mantle/platform/machine/qemu"
28+
"github.com/coreos/coreos-assembler/mantle/util"
29+
)
30+
31+
// https://github.com/coreos/coreos-assembler/pull/3998#issuecomment-2589994641
32+
var nfs_server_butane = conf.Butane(`variant: fcos
33+
version: 1.5.0
34+
storage:
35+
directories:
36+
- path: /var/nfs1/share
37+
mode: 0777
38+
- path: /var/nfs2/share
39+
mode: 0777
40+
- path: /var/nfs3/share
41+
mode: 0777
42+
- path: /var/nfs4/share
43+
mode: 0777
44+
- path: /var/nfs5/share
45+
mode: 0777
46+
- path: /var/nfs6/share
47+
mode: 0777
48+
files:
49+
- path: "/etc/exports"
50+
overwrite: true
51+
contents:
52+
inline: |
53+
/var/nfs1/share *(rw,insecure,no_root_squash)
54+
/var/nfs2/share *(rw,insecure,no_root_squash)
55+
/var/nfs3/share *(rw,insecure,no_root_squash)
56+
/var/nfs4/share *(rw,insecure,no_root_squash)
57+
/var/nfs5/share *(rw,insecure,no_root_squash)
58+
/var/nfs6/share *(rw,insecure,no_root_squash)
59+
- path: "/var/lib/nfs/etab"
60+
systemd:
61+
units:
62+
- name: "nfs-server.service"
63+
enabled: true`)
64+
65+
func init() {
66+
register.RegisterTest(&register.Test{
67+
// See https://github.com/ostreedev/ostree/pull/2968
68+
Run: ostreeSyncTest,
69+
ClusterSize: 0,
70+
Name: "ostree.sync",
71+
Description: "Verify ostree can sync the filesystem with disconnected the NFS volume.",
72+
Distros: []string{"rhcos"},
73+
Platforms: []string{"qemu"},
74+
Tags: []string{"ostree", kola.SkipBaseChecksTag, kola.NeedsInternetTag},
75+
})
76+
}
77+
78+
// NFS server
79+
type NfsServer struct {
80+
Machine platform.Machine
81+
MachineAddress string
82+
}
83+
84+
func setupNFSMachine(c cluster.TestCluster) NfsServer {
85+
var m platform.Machine
86+
var err error
87+
var nfs_server string
88+
89+
options := platform.QemuMachineOptions{
90+
HostForwardPorts: []platform.HostForwardPort{
91+
{Service: "ssh", HostPort: 0, GuestPort: 22},
92+
{Service: "nfs", HostPort: 2049, GuestPort: 2049},
93+
},
94+
}
95+
options.MinMemory = 2048
96+
97+
// start the machine
98+
switch c := c.Cluster.(type) {
99+
// These cases have to be separated because when put together to the same case statement
100+
// the golang compiler no longer checks that the individual types in the case have the
101+
// NewMachineWithQemuOptions function, but rather whether platform.Cluster
102+
// does which fails
103+
case *qemu.Cluster:
104+
m, err = c.NewMachineWithQemuOptions(nfs_server_butane, options)
105+
nfs_server = "10.0.2.2"
106+
default:
107+
m, err = c.NewMachine(nfs_server_butane)
108+
nfs_server = m.PrivateIP()
109+
}
110+
if err != nil {
111+
c.Fatal(err)
112+
}
113+
114+
// Wait for nfs server to become active
115+
err = util.Retry(6, 10*time.Second, func() error {
116+
nfs_status := c.MustSSH(m, "systemctl is-active nfs-server.service")
117+
if string(nfs_status) != "active" {
118+
return fmt.Errorf("nfs-server.service is not ready: %s.", string(nfs_status))
119+
}
120+
return nil
121+
})
122+
if err != nil {
123+
c.Fatalf("Timeout(1m) while waiting for nfs-server.service to be ready: %v", err)
124+
}
125+
return NfsServer{
126+
Machine: m,
127+
MachineAddress: nfs_server,
128+
}
129+
}
130+
131+
// Refer to the steps:
132+
// https://issues.redhat.com/browse/ECOENGCL-91?focusedId=26272587&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-26272587
133+
func ostreeSyncTest(c cluster.TestCluster) {
134+
// Start nfs server machine
135+
nfs_server := setupNFSMachine(c)
136+
137+
// Start test machine
138+
butane := conf.Butane(`variant: fcos
139+
version: 1.5.0
140+
storage:
141+
directories:
142+
- path: /var/tmp/data1
143+
mode: 0777
144+
- path: /var/tmp/data2
145+
mode: 0777
146+
- path: /var/tmp/data3
147+
mode: 0777
148+
- path: /var/tmp/data4
149+
mode: 0777
150+
- path: /var/tmp/data5
151+
mode: 0777
152+
- path: /var/tmp/data6
153+
mode: 0777
154+
files:
155+
- path: /etc/systemd/system.conf
156+
overwrite: true
157+
contents:
158+
inline: |
159+
[Manager]
160+
DefaultTimeoutStopSec=10s
161+
- path: /usr/local/bin/nfs-random-write.sh
162+
mode: 0755
163+
overwrite: true
164+
contents:
165+
inline: |
166+
#!/bin/bash
167+
for i in $(seq 6); do
168+
(while sudo rm -f /var/tmp/data$i/test; do
169+
for x in $(seq 6); do
170+
set -x;
171+
sudo dd if=/dev/urandom of=/var/tmp/data$i/test bs=4096 count=2048 conv=notrunc oflag=append &> /dev/null;
172+
set +x;
173+
sleep 0.5;
174+
done;
175+
done) &
176+
done
177+
`)
178+
opts := platform.MachineOptions{
179+
MinMemory: 2048,
180+
}
181+
var nfs_client platform.Machine
182+
var err error
183+
184+
switch c := c.Cluster.(type) {
185+
case *qemu.Cluster:
186+
nfs_client, err = c.NewMachineWithOptions(butane, opts)
187+
default:
188+
nfs_client, err = c.NewMachine(butane)
189+
}
190+
if err != nil {
191+
c.Fatalf("Unable to create test machine: %v", err)
192+
}
193+
194+
// Wait for test machine
195+
err = util.Retry(6, 10*time.Second, func() error {
196+
_ = c.MustSSHf(nfs_client, `for i in $(seq 6); do
197+
sudo mount -t nfs4 %s:/var/nfs$i/share /var/tmp/data$i
198+
done`, nfs_server.MachineAddress)
199+
200+
mounts := c.MustSSH(nfs_client, "sudo df -Th | grep nfs | wc -l")
201+
if string(mounts) != "6" {
202+
c.Fatalf("Can not mount all nfs")
203+
}
204+
c.Log("Got NFS mount.")
205+
return nil
206+
})
207+
if err != nil {
208+
c.Fatalf("Timeout(1m) to get nfs mount: %v", err)
209+
}
210+
211+
doSyncTest(c, nfs_client)
212+
}
213+
214+
func doSyncTest(c cluster.TestCluster, client platform.Machine) {
215+
c.RunCmdSync(client, "sudo touch /var/tmp/data3/test")
216+
// Continue write
217+
go func() {
218+
_, err := c.SSH(client, "sudo sh /usr/local/bin/nfs-random-write.sh")
219+
if err != nil {
220+
c.Fatalf("failed to start write-to-nfs: %v", err)
221+
}
222+
}()
223+
224+
// Create a stage deploy using kargs while writing
225+
c.RunCmdSync(client, "sudo rpm-ostree kargs --append=test=1")
226+
227+
netdevices := c.MustSSH(client, "ls /sys/class/net | grep -v lo")
228+
netdevice := string(netdevices)
229+
if netdevice == "" {
230+
c.Fatalf("failed to get net device")
231+
}
232+
c.Log("Set link down and rebooting.")
233+
// Skip the error check as it is expected
234+
cmd := fmt.Sprintf("sudo systemd-run sh -c 'ip link set %s down && sleep 2 && systemctl reboot'", netdevice)
235+
_, _ = c.SSH(client, cmd)
236+
237+
time.Sleep(5 * time.Second)
238+
err := util.Retry(8, 10*time.Second, func() error {
239+
// Look for the kernel argument test=1
240+
kernelArguments, err := c.SSH(client, "cat /proc/cmdline")
241+
if err != nil {
242+
return err
243+
} else if !strings.Contains(string(kernelArguments), "test=1") {
244+
c.Fatalf("Not found test=1 in kernel argument after rebooted")
245+
}
246+
return nil
247+
})
248+
if err != nil {
249+
c.Fatalf("Unable to reboot machine: %v", err)
250+
}
251+
c.Log("Found test=1 in kernel argument after rebooted.")
252+
}

0 commit comments

Comments
 (0)