Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read, Write, Copy, Rename tests [Readonly Filesystem] #1080

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
56e868d
secreat
Tulsishah Apr 11, 2023
f60cfea
secreat
Tulsishah Apr 11, 2023
6cb073c
secreat
Tulsishah Apr 11, 2023
46d1ac5
secreat
Tulsishah Apr 11, 2023
27b65d5
secreat
Tulsishah Apr 11, 2023
d54a6b3
secreat
Tulsishah Apr 11, 2023
59d9835
secreat
Tulsishah Apr 11, 2023
dc35dd0
secreat
Tulsishah Apr 11, 2023
7af33bf
secreat
Tulsishah Apr 11, 2023
47ba602
removing unnecessary line
Tulsishah Apr 12, 2023
e632aed
Merge branch 'GoogleCloudPlatform:master' into master
Tulsishah Apr 17, 2023
9c78554
Merge branch 'GoogleCloudPlatform:master' into master
Tulsishah Apr 18, 2023
3a29347
Merge branch 'GoogleCloudPlatform:master' into master
Tulsishah Apr 19, 2023
fc2e359
adding read tests
Tulsishah Apr 21, 2023
f36fbe8
adding tests for write
Tulsishah Apr 21, 2023
cdcfde4
adding copy tests
Tulsishah Apr 21, 2023
5468885
adding rename file tests
Tulsishah Apr 21, 2023
02de529
small fix
Tulsishah Apr 21, 2023
299e386
small fix
Tulsishah Apr 21, 2023
c0aff8d
Merge branch 'GoogleCloudPlatform:master' into create_read_write_test
Tulsishah Apr 21, 2023
90a473e
updating with variable name
Tulsishah Apr 21, 2023
147f13e
updating function name
Tulsishah Apr 21, 2023
581488a
small fix
Tulsishah Apr 21, 2023
57007cc
adding comment for functions
Tulsishah Apr 21, 2023
a0af96a
fixing dirPath in rename tests
Tulsishah Apr 21, 2023
1978fc2
adding test cases for non exist file
Tulsishah Apr 21, 2023
addb7b6
changing function name
Tulsishah Apr 21, 2023
4cc3159
formating
Tulsishah Apr 21, 2023
ba547eb
separeting tests
Tulsishah Apr 24, 2023
87ff41f
fix comments
Tulsishah Apr 24, 2023
3f380c1
adding comment
Tulsishah Apr 24, 2023
765ace0
fixing comments
Tulsishah Apr 25, 2023
584fedb
small fix
Tulsishah Apr 25, 2023
62a2008
revert changes to remove dependency on third party
Tulsishah Apr 25, 2023
466047b
local testing
Tulsishah Apr 25, 2023
323fe58
resolving commit
Tulsishah Apr 27, 2023
2a21aaa
resolving commit
Tulsishah Apr 27, 2023
188724c
updating tests
Tulsishah Apr 27, 2023
0897454
updating function names
Tulsishah Apr 27, 2023
44691a1
adding tests for subdirectory file
Tulsishah Apr 28, 2023
f915f47
Merge branch 'GoogleCloudPlatform:master' into create_read_write_test
Tulsishah May 3, 2023
a8650c0
fixing comments
Tulsishah May 3, 2023
75bc276
small fix
Tulsishah May 3, 2023
840074b
updating comment
Tulsishah May 3, 2023
8dd361f
fix comments - updating comment
Tulsishah May 3, 2023
0a5c80b
Adding comment
Tulsishah May 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions tools/integration_tests/readonly/copy_object_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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 file operations with --o=ro flag set.
package readonly_test

import (
"io"
"os"
"os/exec"
"path"
"syscall"
"testing"

"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/setup"
)

// Copy srcFile in testBucket/Test/b/b.txt destination.
func checkIfFileCopyFailed(srcFilePath string, t *testing.T) {
source, err := os.OpenFile(srcFilePath, syscall.O_DIRECT, setup.FilePermission_0600)
if err != nil {
t.Errorf("Error in the opening file: %v", err)
}

// cp without destination file creates a destination file and create workflow is already covered separately.
// Checking if destination object exist.
copyFile := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket, FileNameInSubDirectoryTestBucket)
Tulsishah marked this conversation as resolved.
Show resolved Hide resolved
if _, err := os.Stat(copyFile); err != nil {
t.Errorf("Copied file %s is not present", copyFile)
}

destination, err := os.OpenFile(copyFile, syscall.O_DIRECT, setup.FilePermission_0600)
if err != nil {
t.Errorf("File %s opening error: %v", destination.Name(), err)
}
defer destination.Close()

// File copying with io.Copy() utility.
// In read only filesystem, io.Copy throws "copy_file_range: bad file descriptor" error.
_, err = io.Copy(destination, source)
if err == nil {
t.Errorf("File copied in read-only file system.")
}
}

// Copy testBucket/Test1.txt to testBucket/Test/b/b.txt
func TestCopyFile(t *testing.T) {
file := path.Join(setup.MntDir(), FileNameInTestBucket)

checkIfFileCopyFailed(file, t)
}

// Copy testBucket/Test/a.txt to testBucket/Test/b/b.txt
func TestCopyFileFromBucketDirectory(t *testing.T) {
file := path.Join(setup.MntDir(), DirectoryNameInTestBucket, FileNameInDirectoryTestBucket)

checkIfFileCopyFailed(file, t)
}

func checkIfDirCopyFailed(srcDirPath string, destDirPath string, t *testing.T) {
// io packages do not have a method to copy the directory.
cmd := exec.Command("cp", "--recursive", srcDirPath, destDirPath)
Tulsishah marked this conversation as resolved.
Show resolved Hide resolved

// In the read-only filesystem, It is Throwing an exit status 1.
err := cmd.Run()
if err == nil {
t.Errorf("Directory copied in read-only file system.")
}
}

// Copy testBucket/Test to testBucket/Test/b
func TestCopyDirectory(t *testing.T) {
srcDir := path.Join(setup.MntDir(), DirectoryNameInTestBucket)
destDir := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket)

checkIfDirCopyFailed(srcDir, destDir, t)
}

// Copy testBucket/Test/b to testBucket
func TestCopySubDirectory(t *testing.T) {
srcDir := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket)
destDir := path.Join(setup.MntDir())

checkIfDirCopyFailed(srcDir, destDir, t)
}
91 changes: 91 additions & 0 deletions tools/integration_tests/readonly/read_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// 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 file operations with --o=ro flag set.
package readonly_test

import (
"os"
"path"
"syscall"
"testing"

"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/setup"
)

func checkIfFileReadSucceeded(filePath string, expectedContent string, t *testing.T) {
file, err := os.OpenFile(filePath, os.O_RDONLY|syscall.O_DIRECT, setup.FilePermission_0600)
if err != nil {
t.Errorf("Error in the opening the file %v", err)
}
defer file.Close()

content, err := os.ReadFile(file.Name())
if err != nil {
t.Errorf("ReadAll: %v", err)
}
if got, want := string(content), expectedContent; got != want {
t.Errorf("File content %q not match %q", got, want)
}
}

// testBucket/Test1.txt
func TestReadFile(t *testing.T) {
filePath := path.Join(setup.MntDir(), FileNameInTestBucket)

checkIfFileReadSucceeded(filePath, ContentInFileInTestBucket, t)
}

// testBucket/Test/a.txt
func TestReadFileFromBucketDirectory(t *testing.T) {
filePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, FileNameInDirectoryTestBucket)

checkIfFileReadSucceeded(filePath, ContentInFileInDirectoryTestBucket, t)
}

// testBucket/Test/b/b.txt
func TestReadFileFromBucketSubDirectory(t *testing.T) {
filePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket, FileNameInSubDirectoryTestBucket)

checkIfFileReadSucceeded(filePath, ContentInFileInSubDirectoryTestBucket, t)
}

func checkIfNonExistentFileFailedToOpen(filePath string, t *testing.T) {
file, err := os.OpenFile(filePath, os.O_RDONLY|syscall.O_DIRECT, setup.FilePermission_0600)

checkErrorForObjectNotExist(err, t)

if err == nil {
t.Errorf("Nonexistent file opened to read.")
}
defer file.Close()
}

func TestReadNonExistentFile(t *testing.T) {
filePath := path.Join(setup.MntDir(), FileNotExist)

checkIfNonExistentFileFailedToOpen(filePath, t)
}

func TestReadNonExistentFileFromBucketDirectory(t *testing.T) {
filePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, FileNotExist)

checkIfNonExistentFileFailedToOpen(filePath, t)
}

func TestReadNonExistentFileFromBucketSubDirectory(t *testing.T) {
filePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket, FileNotExist)

checkIfNonExistentFileFailedToOpen(filePath, t)
}
10 changes: 8 additions & 2 deletions tools/integration_tests/readonly/readonly_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ const FileNameInDirectoryTestBucket = "a.txt" // testBucket/Test/a.txt
const FileNameInSubDirectoryTestBucket = "b.txt" // testBucket/Test/b/b.txt
const NumberOfObjectsInTestBucket = 2
const NumberOfObjectsInDirectoryTestBucket = 2
const NumberOfObjectsInSubDirectoryTestBucket = 1
const FileNotExist = "notExist.txt"
const DirNotExist = "notExist"
const ContentInFileInTestBucket = "This is from file Test1\n"
const ContentInFileInDirectoryTestBucket = "This is from directory Test file a\n"
const ContentInFileInSubDirectoryTestBucket = "This is from directory Test/b file b\n"
const RenameFile = "rename.txt"
const RenameDir = "rename"

// Run shell script
func runScriptForTestData(script string, testBucket string) {
Expand All @@ -45,13 +51,13 @@ func runScriptForTestData(script string, testBucket string) {

func checkErrorForReadOnlyFileSystem(err error, t *testing.T) {
if !strings.Contains(err.Error(), "read-only file system") && !strings.Contains(err.Error(), "permission denied") {
t.Errorf("Incorrect error for readonly filesystem.")
t.Errorf("Incorrect error for readonly filesystem: %v", err.Error())
}
}

func checkErrorForObjectNotExist(err error, t *testing.T) {
if !strings.Contains(err.Error(), "no such file or directory") {
t.Errorf("Incorrect error for object not exist.")
t.Errorf("Incorrect error for object not exist: %v", err.Error())
}
}

Expand Down
140 changes: 140 additions & 0 deletions tools/integration_tests/readonly/rename_object_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// 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 file operations with --o=ro flag set.
package readonly_test

import (
"os"
"path"
"testing"

"github.com/googlecloudplatform/gcsfuse/tools/integration_tests/setup"
)

// Rename oldObj to newObj
func checkIfRenameFailed(oldObjPath string, newObjPath string, t *testing.T) {
_, err := os.Stat(oldObjPath)
if err != nil {
t.Errorf("Error in the stating object: %v", err)
}

if _, err := os.Stat(newObjPath); err == nil {
t.Errorf("Renamed object %s already present", newObjPath)
}

err = os.Rename(oldObjPath, newObjPath)

if err == nil {
t.Errorf("Object renamed in read-only file system.")
}

checkErrorForReadOnlyFileSystem(err, t)

if _, err := os.Stat(oldObjPath); err != nil {
t.Errorf("OldObj is deleted in read-only file system.")
}
if _, err := os.Stat(newObjPath); err == nil {
t.Errorf("Renamed object found in read-only file system.")
}
}

// Rename testBucket/Test1.txt to testBucket/Rename.txt
func TestRenameFile(t *testing.T) {
oldFilePath := path.Join(setup.MntDir(), FileNameInTestBucket)
newFilePath := path.Join(setup.MntDir(), RenameFile)

checkIfRenameFailed(oldFilePath, newFilePath, t)
}

// Rename testBucket/Test/a.txt to testBucket/Test/Rename.txt
func TestRenameFileFromBucketDirectory(t *testing.T) {
oldFilePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, FileNameInDirectoryTestBucket)
newFilePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, RenameFile)

checkIfRenameFailed(oldFilePath, newFilePath, t)
}

// Rename testBucket/Test/b/b.txt to testBucket/Test/b/Rename.txt
func TestRenameFileFromBucketSubDirectory(t *testing.T) {
oldFilePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket, FileNameInSubDirectoryTestBucket)
newFilePath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket, RenameFile)

checkIfRenameFailed(oldFilePath, newFilePath, t)
}

// Rename testBucket/Test to testBucket/Rename
func TestRenameDir(t *testing.T) {
oldDirPath := path.Join(setup.MntDir(), DirectoryNameInTestBucket)
newDirPath := path.Join(setup.MntDir(), RenameDir)

checkIfRenameFailed(oldDirPath, newDirPath, t)

// Ensure none of the child is deleted during the directory rename test.
// ** OldDirectory structure **
// Test
// Test/b -- Dir
// Test/a.txt -- File

obj, err := os.ReadDir(oldDirPath)
if err != nil {
t.Errorf("Error in reading directory %v ,", err.Error())
}

// Comparing number of objects in the oldDirectory - 2
if len(obj) != NumberOfObjectsInDirectoryTestBucket {
t.Errorf("The number of objects in the current directory doesn't match.")
}

// Comparing first object name and type
// Name - Test/a.txt, Type - File
if obj[0].Name() != FileNameInDirectoryTestBucket || obj[0].IsDir() != false {
t.Errorf("Object Listed for file in bucket is incorrect.")
}

// Comparing second object name and type
// Name - Test/b , Type - Dir
if obj[1].Name() != SubDirectoryNameInTestBucket || obj[1].IsDir() != true {
t.Errorf("Object Listed for bucket directory is incorrect.")
}
}

// Rename testBucket/Test/b to testBucket/Test/Rename
func TestRenameSubDirectory(t *testing.T) {
oldDirPath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, SubDirectoryNameInTestBucket)
newDirPath := path.Join(setup.MntDir(), DirectoryNameInTestBucket, RenameDir)

checkIfRenameFailed(oldDirPath, newDirPath, t)

// Ensure none of the child is deleted during the directory rename test.
// ** OldDirectory structure **
// b
// b/b.txt -- File

obj, err := os.ReadDir(oldDirPath)
if err != nil {
t.Errorf("Error in reading directory %v ,", err.Error())
}

// Comparing number of objects in the oldDirectory - 1
if len(obj) != NumberOfObjectsInSubDirectoryTestBucket {
t.Errorf("The number of objects in the current directory doesn't match.")
}

// Comparing object name and type
// Name - b/b.txt, Type - File
if obj[0].Name() != FileNameInSubDirectoryTestBucket || obj[0].IsDir() != false {
t.Errorf("Object Listed for file in bucket SubDirectory is incorrect.")
}
}
Loading