Skip to content

Commit 7dd4b4d

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 c9df100 commit 7dd4b4d

File tree

1 file changed

+249
-0
lines changed

1 file changed

+249
-0
lines changed

mantle/kola/tests/ostree/sync.go

+249
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
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+
Tags: []string{"ostree", kola.SkipBaseChecksTag, kola.NeedsInternetTag},
74+
})
75+
}
76+
77+
// NFS server
78+
type NfsServer struct {
79+
Machine platform.Machine
80+
MachineAddress string
81+
}
82+
83+
func setupNFSMachine(c cluster.TestCluster) NfsServer {
84+
var m platform.Machine
85+
var err error
86+
var nfs_server string
87+
88+
options := platform.QemuMachineOptions{
89+
HostForwardPorts: []platform.HostForwardPort{
90+
{Service: "ssh", HostPort: 0, GuestPort: 22},
91+
{Service: "nfs", HostPort: 2049, GuestPort: 2049},
92+
},
93+
}
94+
options.MinMemory = 2048
95+
96+
// start the machine
97+
switch c := c.Cluster.(type) {
98+
// These cases have to be separated because when put together to the same case statement
99+
// the golang compiler no longer checks that the individual types in the case have the
100+
// NewMachineWithQemuOptions function, but rather whether platform.Cluster
101+
// does which fails
102+
case *qemu.Cluster:
103+
m, err = c.NewMachineWithQemuOptions(nfs_server_butane, options)
104+
nfs_server = "10.0.2.2"
105+
default:
106+
m, err = c.NewMachine(nfs_server_butane)
107+
nfs_server = m.PrivateIP()
108+
}
109+
if err != nil {
110+
c.Fatal(err)
111+
}
112+
113+
// Wait for nfs server to become active
114+
err = util.Retry(6, 10*time.Second, func() error {
115+
nfs_status := c.MustSSH(m, "systemctl is-active nfs-server.service")
116+
if string(nfs_status) != "active" {
117+
return fmt.Errorf("nfs-server.service is not ready: %s.", string(nfs_status))
118+
}
119+
return nil
120+
})
121+
if err != nil {
122+
c.Fatalf("Timeout(1m) while waiting for nfs-server.service to be ready: %v", err)
123+
}
124+
return NfsServer{
125+
Machine: m,
126+
MachineAddress: nfs_server,
127+
}
128+
}
129+
130+
// Refer to the steps:
131+
// https://issues.redhat.com/browse/ECOENGCL-91?focusedId=26272587&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-26272587
132+
func ostreeSyncTest(c cluster.TestCluster) {
133+
// Start nfs server machine
134+
nfs_server := setupNFSMachine(c)
135+
136+
// Start test machine
137+
butane := conf.Butane(`variant: fcos
138+
version: 1.5.0
139+
storage:
140+
directories:
141+
- path: /var/tmp/data1
142+
mode: 0777
143+
- path: /var/tmp/data2
144+
mode: 0777
145+
- path: /var/tmp/data3
146+
mode: 0777
147+
- path: /var/tmp/data4
148+
mode: 0777
149+
- path: /var/tmp/data5
150+
mode: 0777
151+
- path: /var/tmp/data6
152+
mode: 0777
153+
files:
154+
- path: /etc/systemd/system.conf
155+
overwrite: true
156+
contents:
157+
inline: |
158+
[Manager]
159+
DefaultTimeoutStopSec=10s
160+
- path: /usr/local/bin/nfs-random-write.sh
161+
mode: 0755
162+
overwrite: true
163+
contents:
164+
inline: |
165+
#!/bin/bash
166+
for i in $(seq 6); do
167+
(while sudo rm -f /var/tmp/data$i/test; do
168+
for x in $(seq 6); do
169+
sudo dd if=/dev/urandom of=/var/tmp/data$i/test bs=4096 count=2048 conv=notrunc oflag=append &> /dev/null;
170+
sleep 0.5;
171+
done;
172+
done) &
173+
done
174+
`)
175+
opts := platform.MachineOptions{
176+
MinMemory: 2048,
177+
}
178+
var nfs_client platform.Machine
179+
var err error
180+
181+
switch c := c.Cluster.(type) {
182+
case *qemu.Cluster:
183+
nfs_client, err = c.NewMachineWithOptions(butane, opts)
184+
default:
185+
nfs_client, err = c.NewMachine(butane)
186+
}
187+
if err != nil {
188+
c.Fatalf("Unable to create test machine: %v", err)
189+
}
190+
191+
// Wait for test machine
192+
err = util.Retry(6, 10*time.Second, func() error {
193+
_ = c.MustSSHf(nfs_client, `for i in $(seq 6); do
194+
sudo mount -t nfs4 %s:/var/nfs$i/share /var/tmp/data$i
195+
done`, nfs_server.MachineAddress)
196+
197+
mounts := c.MustSSH(nfs_client, "sudo df -Th | grep nfs | wc -l")
198+
if string(mounts) != "6" {
199+
c.Fatalf("Can not mount all nfs")
200+
}
201+
c.Log("Got NFS mount.")
202+
return nil
203+
})
204+
if err != nil {
205+
c.Fatalf("Timeout(1m) to get nfs mount: %v", err)
206+
}
207+
208+
doSyncTest(c, nfs_client)
209+
}
210+
211+
func doSyncTest(c cluster.TestCluster, client platform.Machine) {
212+
c.RunCmdSync(client, "sudo touch /var/tmp/data3/test")
213+
// Continue write
214+
go func() {
215+
_, err := c.SSH(client, "sudo sh /usr/local/bin/nfs-random-write.sh")
216+
if err != nil {
217+
c.Fatalf("failed to start write-to-nfs: %v", err)
218+
}
219+
}()
220+
221+
// Create a stage deploy using kargs while writing
222+
c.RunCmdSync(client, "sudo rpm-ostree kargs --append=test=1")
223+
224+
netdevices := c.MustSSH(client, "ls /sys/class/net | grep -v lo")
225+
netdevice := string(netdevices)
226+
if netdevice == "" {
227+
c.Fatalf("failed to get net device")
228+
}
229+
c.Log("Set link down and rebooting.")
230+
// Skip the error check as it is expected
231+
cmd := fmt.Sprintf("sudo systemd-run sh -c 'ip link set %s down && sleep 2 && systemctl reboot'", netdevice)
232+
_, _ = c.SSH(client, cmd)
233+
234+
time.Sleep(5 * time.Second)
235+
err := util.Retry(8, 10*time.Second, func() error {
236+
// Look for the kernel argument test=1
237+
kernelArguments, err := c.SSH(client, "cat /proc/cmdline")
238+
if err != nil {
239+
return err
240+
} else if !strings.Contains(string(kernelArguments), "test=1") {
241+
c.Fatalf("Not found test=1 in kernel argument after rebooted")
242+
}
243+
return nil
244+
})
245+
if err != nil {
246+
c.Fatalf("Unable to reboot machine: %v", err)
247+
}
248+
c.Log("Found test=1 in kernel argument after rebooted.")
249+
}

0 commit comments

Comments
 (0)