Skip to content

Commit b206264

Browse files
committed
Shorten long directory names with e2e pod logs
In a downstream test job, I've seen an e2e test failing to create a directory for Pod logs when running an e2e test. Shorten them to 255 characters. For example, consider this test: "[sig-storage] CSI Mock selinux on mount metrics and SELinuxWarningController SELinuxMount metrics [LinuxOnly] [Feature:SELinux] [Serial] error is not bumped on two Pods with a different policy RWX volume (MountOption + MountOption) [FeatureGate:SELinuxMountReadWriteOncePod] [Beta] [FeatureGate:SELinuxChangePolicy] [Beta] [FeatureGate:SELinuxMount] [Beta] [Feature:OffByDefault] [sig-storage, Feature:SELinux, Serial, FeatureGate:SELinuxMountReadWriteOncePod, Beta, FeatureGate:SELinuxChangePolicy, FeatureGate:SELinuxMount, Feature:OffByDefault, BetaOffByDefault]" During execution, the test will create a directory `error_is_not_bumped_on_two_Pods_with_Recursive_policy_and_a_different_context_on_RWX_volume_FeatureGate_SELinuxMountReadWriteOncePod_Beta_FeatureGate_SELinuxChangePolicy_Beta_FeatureGate_SELinuxMount_Beta_Feature_OffByDefault_`, which has 226 characters and it's close to the limit (256).
1 parent cacd595 commit b206264

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

test/e2e/storage/utils/file.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package utils
18+
19+
import (
20+
"fmt"
21+
"hash/crc32"
22+
)
23+
24+
// The max length for ntfs, ext4, xfs and btrfs.
25+
const maxFileNameLength = 255
26+
27+
// Shorten a file name to size allowed by the most common filesystems.
28+
// If the filename is too long, cut it + add a short hash (crc32) that makes it unique.
29+
// Note that the input should be a single file / directory name, not a path
30+
// composed of several directories.
31+
func ShortenFileName(filename string) string {
32+
if len(filename) <= maxFileNameLength {
33+
return filename
34+
}
35+
36+
hash := crc32.ChecksumIEEE([]byte(filename))
37+
hashString := fmt.Sprintf("%x", hash)
38+
hashLen := len(hashString)
39+
40+
return fmt.Sprintf("%s-%s", filename[:maxFileNameLength-1-hashLen], hashString)
41+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package utils
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
)
24+
25+
func TestShortenFileName(t *testing.T) {
26+
tests := []struct {
27+
name string
28+
filename string
29+
expected string
30+
}{
31+
{
32+
name: "Shorter than max length",
33+
filename: "short file name",
34+
expected: "short file name",
35+
},
36+
{
37+
name: "Longer than max length, truncated",
38+
filename: "a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 characters..",
39+
expected: "a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 characters a very long string that has exactly 256 ch-ad31f675",
40+
},
41+
{
42+
name: "Exactly max length, not truncated",
43+
filename: "a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters.",
44+
expected: "a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters a very long string that has exactly 255 characters.",
45+
},
46+
}
47+
48+
for _, tt := range tests {
49+
t.Run(tt.name, func(t *testing.T) {
50+
result := ShortenFileName(tt.filename)
51+
assert.Equal(t, tt.expected, result)
52+
assert.LessOrEqual(t, len(result), maxFileNameLength)
53+
})
54+
}
55+
}

test/e2e/storage/utils/pod.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import (
2222
"io"
2323
"os"
2424
"path"
25+
"path/filepath"
2526
"regexp"
26-
"strings"
2727

2828
"github.com/onsi/ginkgo/v2"
2929
"github.com/onsi/gomega"
@@ -68,6 +68,12 @@ func StartPodLogs(ctx context.Context, f *framework.Framework, driverNamespace *
6868
testName = append(testName, reg.ReplaceAllString(test.LeafNodeText, "_"))
6969
}
7070
}
71+
72+
// Make sure each directory name is short enough for Linux + Windows
73+
for i, testNameComponent := range testName {
74+
testName[i] = ShortenFileName(testNameComponent)
75+
}
76+
7177
// We end the prefix with a slash to ensure that all logs
7278
// end up in a directory named after the current test.
7379
//
@@ -76,7 +82,7 @@ func StartPodLogs(ctx context.Context, f *framework.Framework, driverNamespace *
7682
// keeps each directory name smaller (the full test
7783
// name at one point exceeded 256 characters, which was
7884
// too much for some filesystems).
79-
logDir := framework.TestContext.ReportDir + "/" + strings.Join(testName, "/")
85+
logDir := filepath.Join(framework.TestContext.ReportDir, filepath.Join(testName...))
8086
to.LogPathPrefix = logDir + "/"
8187

8288
err := os.MkdirAll(logDir, 0755)

0 commit comments

Comments
 (0)