-
Notifications
You must be signed in to change notification settings - Fork 430
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate with lumberjack for log rotation (#1504)
* integrate with lumberjack * run perf test * fix fio error * fix operations tests * reduce number of log rotations to reduce integration test execution time * review comments * temp commit to run perf tests with trace logs * fix lint issues * temp commit * review comments * fix lint * revert perf changes * refactoring based on review comments
- Loading branch information
1 parent
2c7d4ed
commit 0288949
Showing
12 changed files
with
324 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
tools/integration_tests/log_rotation/log_rotation_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2023 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Provides integration tests for log rotation of gcsfuse logs. | ||
|
||
package log_rotation | ||
|
||
import ( | ||
"os" | ||
"path" | ||
"testing" | ||
|
||
"github.com/googlecloudplatform/gcsfuse/internal/config" | ||
"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/util/mounting/static_mounting" | ||
"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/util/setup" | ||
) | ||
|
||
const ( | ||
testDirName = "LogRotationTest" | ||
logFileName = "log.txt" | ||
logDirName = "gcsfuse_integration_test_logs" | ||
maxFileSizeMB = 2 | ||
activeLogFileCount = 1 | ||
backupLogFileCount = 2 | ||
logFileCount = activeLogFileCount + backupLogFileCount | ||
) | ||
|
||
var logDirPath string | ||
var logFilePath string | ||
|
||
func getMountConfigForLogRotation(maxFileSizeMB, fileCount int, compress bool, | ||
logFilePath string) config.MountConfig { | ||
mountConfig := config.MountConfig{ | ||
LogConfig: config.LogConfig{ | ||
Severity: config.TRACE, | ||
FilePath: logFilePath, | ||
LogRotateConfig: config.LogRotateConfig{ | ||
MaxFileSizeMB: maxFileSizeMB, | ||
FileCount: fileCount, | ||
Compress: compress, | ||
}, | ||
}, | ||
} | ||
return mountConfig | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////// | ||
// TestMain | ||
//////////////////////////////////////////////////////////////////////// | ||
|
||
func TestMain(m *testing.M) { | ||
setup.ParseSetUpFlags() | ||
|
||
setup.ExitWithFailureIfBothTestBucketAndMountedDirectoryFlagsAreNotSet() | ||
|
||
// Run tests for mountedDirectory only if --mountedDirectory flag is set. | ||
|
||
logDirPath = setup.ValidateLogDirForMountedDirTests(logDirName) | ||
logFilePath = path.Join(logDirPath, logFileName) | ||
setup.RunTestsForMountedDirectoryFlag(m) | ||
|
||
// Else run tests for testBucket. | ||
// Set up test directory. | ||
setup.SetUpTestDirForTestBucketFlag() | ||
|
||
// Set up directory for logs. | ||
logDirPath = setup.SetUpLogDirForTestDirTests(logDirName) | ||
logFilePath = path.Join(logDirPath, logFileName) | ||
|
||
// Set up config files. | ||
configFile1 := setup.YAMLConfigFile( | ||
getMountConfigForLogRotation(maxFileSizeMB, logFileCount, true, logFilePath), | ||
"config1.yaml") | ||
configFile2 := setup.YAMLConfigFile( | ||
getMountConfigForLogRotation(maxFileSizeMB, logFileCount, false, logFilePath), | ||
"config2.yaml") | ||
|
||
// Set up flags to run tests on. | ||
// Not setting config file explicitly with 'create-empty-file: false' as it is default. | ||
flags := [][]string{ | ||
{"--config-file=" + configFile1}, | ||
{"--config-file=" + configFile2}, | ||
} | ||
|
||
successCode := static_mounting.RunTests(flags, m) | ||
|
||
// Clean up test directory created. | ||
setup.CleanupDirectoryOnGCS(path.Join(setup.TestBucket(), testDirName)) | ||
setup.RemoveBinFileCopiedForTesting() | ||
os.Exit(successCode) | ||
} |
139 changes: 139 additions & 0 deletions
139
tools/integration_tests/log_rotation/logrotate_logfile_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// Copyright 2023 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package log_rotation | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path" | ||
"strings" | ||
"sync" | ||
"testing" | ||
"time" | ||
|
||
"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/util/operations" | ||
"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/util/setup" | ||
) | ||
|
||
const ( | ||
MiB = 1024 * 1024 | ||
filePerms = 0644 | ||
testFileName = "foo" | ||
) | ||
|
||
//////////////////////////////////////////////////////////////////////// | ||
// Helpers | ||
//////////////////////////////////////////////////////////////////////// | ||
|
||
func runOperationsOnFileTillLogRotation(t *testing.T, wg *sync.WaitGroup, fileName string) { | ||
defer wg.Done() | ||
|
||
// Generate random data to write to file. | ||
randomData, err := operations.GenerateRandomData(5 * MiB) | ||
if err != nil { | ||
t.Errorf("operations.GenerateRandomData: %v", err) | ||
} | ||
// Setup file with 5 MiB content in test directory. | ||
testDirPath := path.Join(setup.MntDir(), testDirName) | ||
filePath := path.Join(testDirPath, fileName) | ||
operations.CreateFileWithContent(filePath, filePerms, string(randomData), t) | ||
|
||
// Keep performing operations in mounted directory until log file is rotated. | ||
var lastLogFileSize int64 = 0 | ||
for { | ||
// Perform Read operation to generate logs. | ||
_, err = operations.ReadFile(filePath) | ||
if err != nil { | ||
t.Errorf("ReadFile failed: %v", err) | ||
} | ||
|
||
// Break the loop when log file is rotated. | ||
fi, err := operations.StatFile(logFilePath) | ||
if err != nil { | ||
t.Errorf("stat operation on file %s: %v", logFilePath, err) | ||
} | ||
if (*fi).Size() < lastLogFileSize { | ||
// Log file got rotated as current log file size < last log file size. | ||
break | ||
} | ||
lastLogFileSize = (*fi).Size() | ||
} | ||
} | ||
|
||
func runParallelOperationsInMountedDirectoryTillLogRotation(t *testing.T) { | ||
// Parallelly performs operations on 5 files in-order to generate logs. | ||
var wg sync.WaitGroup | ||
wg.Add(5) | ||
for i := 0; i < 5; i++ { | ||
go runOperationsOnFileTillLogRotation(t, &wg, fmt.Sprintf(testFileName+"-%d", i)) | ||
} | ||
wg.Wait() | ||
} | ||
|
||
func validateLogFileSize(t *testing.T, dirEntry os.DirEntry) { | ||
fi, err := dirEntry.Info() | ||
if err != nil { | ||
t.Fatalf("log file size could not be fetched: %v", err) | ||
} | ||
if fi.Size() > maxFileSizeMB*MiB { | ||
t.Errorf("log file size: expected (max): %d, actual: %d", maxFileSizeMB*MiB, fi.Size()) | ||
} | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////// | ||
// Tests | ||
//////////////////////////////////////////////////////////////////////// | ||
|
||
func TestLogRotation(t *testing.T) { | ||
setup.SetupTestDirectory(testDirName) | ||
|
||
// Perform log rotation 4 times. | ||
for i := 0; i < 4; i++ { | ||
runParallelOperationsInMountedDirectoryTillLogRotation(t) | ||
} | ||
// Adding 1-second sleep here because there is slight delay in compression | ||
// of log files. | ||
time.Sleep(1 * time.Second) | ||
|
||
// Validate log files generated. | ||
dirEntries := operations.ReadDirectory(logDirPath, t) | ||
if len(dirEntries) != logFileCount { | ||
t.Errorf("Expected log files in dirEntries folder: %d, got: %d", | ||
logFileCount, len(dirEntries)) | ||
} | ||
rotatedCompressedFileCtr := 0 | ||
logFileCtr := 0 | ||
rotatedUncompressedFileCtr := 0 | ||
for i := 0; i < logFileCount; i++ { | ||
if dirEntries[i].Name() == logFileName { | ||
logFileCtr++ | ||
validateLogFileSize(t, dirEntries[i]) | ||
} else if strings.Contains(dirEntries[i].Name(), "txt.gz") { | ||
rotatedCompressedFileCtr++ | ||
} else { | ||
rotatedUncompressedFileCtr++ | ||
validateLogFileSize(t, dirEntries[i]) | ||
} | ||
} | ||
|
||
if logFileCtr != activeLogFileCount { | ||
t.Errorf("expected countOfLogFile: %d, got: %d", activeLogFileCount, logFileCtr) | ||
} | ||
|
||
rotatedLogFiles := rotatedCompressedFileCtr + rotatedUncompressedFileCtr | ||
if rotatedLogFiles != backupLogFileCount { | ||
t.Errorf("expected rotated files: %d, got: %d", backupLogFileCount, rotatedLogFiles) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.