mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-23 22:29:59 -05:00
run all tests with POSIX_WATCH_FS=true (#1342)
This commit is contained in:
@@ -2089,7 +2089,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depend
|
||||
},
|
||||
"commands": [
|
||||
"apt-get update",
|
||||
"apt-get install -y inotify-tools",
|
||||
"apt-get install -y inotify-tools xattr",
|
||||
"%s init --insecure true" % dirs["opencloudBin"],
|
||||
"cat $OC_CONFIG_DIR/opencloud.yaml",
|
||||
"cp tests/config/woodpecker/app-registry.yaml $OC_CONFIG_DIR/app-registry.yaml",
|
||||
|
||||
@@ -41,7 +41,12 @@ class CliContext implements Context {
|
||||
*/
|
||||
public static function getUsersStoragePath(): string {
|
||||
$path = getenv('OC_STORAGE_PATH') ?: '/var/lib/opencloud/storage/users';
|
||||
return $path . '/users';
|
||||
// need for CI
|
||||
$home = getenv('HOME');
|
||||
$path = preg_replace('#^~/#', $home . '/', $path);
|
||||
$path = str_replace('$HOME', $home, $path);
|
||||
|
||||
return rtrim($path, '/') . '/users';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +74,51 @@ class CliContext implements Context {
|
||||
$this->spacesContext = BehatHelper::getContext($scope, $environment, 'SpacesContext');
|
||||
}
|
||||
|
||||
/**
|
||||
* expects a file to exist at the given path
|
||||
*
|
||||
* @param string $path
|
||||
* @param string|null $sizeGb
|
||||
* @param int $maxSeconds
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function waitForPath(string $path, ?string $sizeGb = null, int $maxSeconds = 10): void {
|
||||
$escapedPath = escapeshellarg($path);
|
||||
|
||||
for ($i = 0; $i < $maxSeconds * 5; $i++) {
|
||||
if ($sizeGb) {
|
||||
if (!preg_match('/^(\d+)gb$/i', $sizeGb, $matches)) {
|
||||
throw new \InvalidArgumentException("Invalid size format: $sizeGb. Use formats like 1gb, 5gb.");
|
||||
}
|
||||
$targetBytes = (int)$matches[1] * 1024 * 1024 * 1024;
|
||||
$body = [
|
||||
"command" => "[ -f $escapedPath ] && stat -c%s $escapedPath || echo 0",
|
||||
"raw" => true
|
||||
];
|
||||
$data = json_decode((string)CliHelper::runCommand($body)->getBody(), true);
|
||||
|
||||
if (isset($data['message']) && (int)trim($data['message']) >= $targetBytes) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$body = [
|
||||
"command" => "ls $escapedPath >/dev/null 2>&1 && echo exists || echo not_exists",
|
||||
"raw" => true
|
||||
];
|
||||
$response = CliHelper::runCommand($body);
|
||||
$data = json_decode((string)$response->getBody(), true);
|
||||
|
||||
if (isset($data['message']) && trim($data['message']) === 'exists') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
usleep(200000);
|
||||
}
|
||||
|
||||
throw new \Exception("Timeout waiting for: $path");
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given the administrator has stopped the server
|
||||
*
|
||||
@@ -468,11 +518,14 @@ class CliContext implements Context {
|
||||
public function theAdministratorCreatesFolder(string $folder, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath();
|
||||
$fullPath = "$storagePath/$userUuid/$folder";
|
||||
|
||||
$body = [
|
||||
"command" => "mkdir -p $storagePath/$userUuid/$folder",
|
||||
"command" => "mkdir -p $fullPath",
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
$this->waitForPath($fullPath);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
@@ -505,12 +558,96 @@ class CliContext implements Context {
|
||||
public function theAdministratorCreatesFile(string $file, string $content, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath();
|
||||
$fullPath = "$storagePath/$userUuid/$file";
|
||||
$safeContent = escapeshellarg($content);
|
||||
$body = [
|
||||
"command" => "echo -n $safeContent > $storagePath/$userUuid/$file",
|
||||
"command" => "echo -n $safeContent > $fullPath",
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
$this->waitForPath($fullPath);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When the administrator creates the file :file with size :size for user :user on the POSIX filesystem
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $size Example: "1gb", "5gb"
|
||||
* @param string $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function theAdministratorCreatesLargeFileWithSize(string $file, string $size, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath();
|
||||
|
||||
$size = strtolower($size);
|
||||
if (!preg_match('/^(\d+)gb$/', $size, $matches)) {
|
||||
throw new \InvalidArgumentException("Invalid size format: $size. Use formats like 1gb, 5gb.");
|
||||
}
|
||||
|
||||
$count = (int)$matches[1] * 1024; // 1GB = 1024M
|
||||
$bs = '1M';
|
||||
$filePath = "$storagePath/$userUuid/$file";
|
||||
|
||||
$body = [
|
||||
"command" => "dd if=/dev/zero of=$filePath bs=$bs count=$count",
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
$this->waitForPath($filePath, $size, 15);
|
||||
sleep(7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When the administrator creates :count files sequentially in the directory :dir for user :user on the POSIX filesystem
|
||||
*
|
||||
* @param int $count
|
||||
* @param string $dir
|
||||
* @param string $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function theAdministratorCreatesFilesSequentially(int $count, string $dir, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath() . "/$userUuid/$dir";
|
||||
$cmd = '';
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$cmd .= "echo -n \"file $i content\" > $storagePath/file_$i.txt; ";
|
||||
}
|
||||
$body = [
|
||||
"command" => $cmd,
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
$this->waitForPath("$storagePath/file_$count.txt");
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When the administrator creates :count files in parallel in the directory :dir for user :user on the POSIX filesystem
|
||||
*
|
||||
* @param int $count
|
||||
* @param string $dir
|
||||
* @param string $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function theAdministratorCreatesFilesInParallel(int $count, string $dir, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath() . "/$userUuid/$dir";
|
||||
$cmd = "mkdir -p $storagePath; ";
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$cmd .= "echo -n \"parallel file $i content\" > $storagePath/parallel_$i.txt & ";
|
||||
}
|
||||
$cmd .= "wait";
|
||||
$body = [
|
||||
"command" => $cmd,
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
$this->waitForPath("$storagePath/parallel_$count.txt");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
@@ -712,4 +849,23 @@ class CliContext implements Context {
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When the administrator checks the attribute :attribute of file :file for user :user on the POSIX filesystem
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $file
|
||||
* @param string $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function theAdminChecksTheAttributeOfFileForUser(string $attribute, string $file, string $user): void {
|
||||
$userUuid = $this->featureContext->getUserIdByUserName($user);
|
||||
$storagePath = $this->getUsersStoragePath();
|
||||
$body = [
|
||||
"command" => "xattr -p -slz " . escapeshellarg($attribute) . " $storagePath/$userUuid/$file",
|
||||
"raw" => true
|
||||
];
|
||||
$this->featureContext->setResponse(CliHelper::runCommand($body));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,26 +4,54 @@ Feature: create a resources using collaborative posixfs
|
||||
Background:
|
||||
Given the config "STORAGE_USERS_POSIX_WATCH_FS" has been set to "true"
|
||||
And user "Alice" has been created with default attributes
|
||||
And user "Alice" has created folder "/firstFolder"
|
||||
|
||||
|
||||
Scenario: administrator lists the content of the POSIX storage
|
||||
Given user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator lists the content of the POSIX storage folder of user "Alice"
|
||||
Then the command output should contain "firstFolder"
|
||||
And the command output should contain "test.txt"
|
||||
|
||||
|
||||
Scenario: create folder
|
||||
Given user "Alice" has uploaded file with content "content" to "textfile.txt"
|
||||
When the administrator creates the folder "myFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
When the administrator lists the content of the POSIX storage folder of user "Alice"
|
||||
Then the command output should contain "myFolder"
|
||||
And as "Alice" folder "/myFolder" should exist
|
||||
|
||||
|
||||
Scenario: create nested folder
|
||||
When the administrator creates the folder "deep/nested/structure/myFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And as "Alice" folder "/deep/nested/structure/myFolder" should exist
|
||||
|
||||
|
||||
Scenario: create file
|
||||
Given user "Alice" has created folder "/folder"
|
||||
When the administrator creates the file "test.txt" with content "content" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
When the administrator lists the content of the POSIX storage folder of user "Alice"
|
||||
Then the command output should contain "test.txt"
|
||||
And the content of file "/test.txt" for user "Alice" should be "content"
|
||||
|
||||
|
||||
Scenario: create large file
|
||||
When the administrator creates the file "largefile.txt" with size "1gb" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And as "Alice" file "/largefile.txt" should exist
|
||||
|
||||
|
||||
Scenario: creates files sequentially in a folder
|
||||
When the administrator creates 50 files sequentially in the directory "firstFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And the content of file "/firstFolder/file_1.txt" for user "Alice" should be "file 1 content"
|
||||
And the content of file "/firstFolder/file_50.txt" for user "Alice" should be "file 50 content"
|
||||
|
||||
|
||||
Scenario: creates files in parallel in a folder
|
||||
When the administrator creates 100 files in parallel in the directory "firstFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And the content of file "/firstFolder/parallel_1.txt" for user "Alice" should be "parallel file 1 content"
|
||||
And the content of file "/firstFolder/parallel_100.txt" for user "Alice" should be "parallel file 100 content"
|
||||
|
||||
|
||||
Scenario: edit file
|
||||
Given user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator puts the content "new" into the file "test.txt" in the POSIX storage folder of user "Alice"
|
||||
@@ -37,11 +65,10 @@ Feature: create a resources using collaborative posixfs
|
||||
|
||||
|
||||
Scenario: copy file to folder
|
||||
Given user "Alice" has created folder "/folder"
|
||||
And user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator copies the file "test.txt" to the folder "folder" for user "Alice" on the POSIX filesystem
|
||||
Given user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator copies the file "test.txt" to the folder "firstFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And the content of file "/folder/test.txt" for user "Alice" should be "content"
|
||||
And the content of file "/firstFolder/test.txt" for user "Alice" should be "content"
|
||||
|
||||
|
||||
Scenario: rename file
|
||||
@@ -52,11 +79,10 @@ Feature: create a resources using collaborative posixfs
|
||||
|
||||
|
||||
Scenario: move file to folder
|
||||
Given user "Alice" has created folder "/folder"
|
||||
And user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator moves the file "test.txt" to the folder "folder" for user "Alice" on the POSIX filesystem
|
||||
Given user "Alice" has uploaded file with content "content" to "test.txt"
|
||||
When the administrator moves the file "test.txt" to the folder "firstFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And the content of file "/folder/test.txt" for user "Alice" should be "content"
|
||||
And the content of file "/firstFolder/test.txt" for user "Alice" should be "content"
|
||||
And as "Alice" file "/test.txt" should not exist
|
||||
|
||||
|
||||
@@ -68,11 +94,10 @@ Feature: create a resources using collaborative posixfs
|
||||
|
||||
|
||||
Scenario: delete folder
|
||||
Given user "Alice" has created folder "/folder"
|
||||
And user "Alice" has uploaded file with content "content" to "/folder/test.txt"
|
||||
When the administrator deletes the folder "folder" for user "Alice" on the POSIX filesystem
|
||||
And user "Alice" has uploaded file with content "content" to "/firstFolder/test.txt"
|
||||
When the administrator deletes the folder "firstFolder" for user "Alice" on the POSIX filesystem
|
||||
Then the command should be successful
|
||||
And as "Alice" folder "folder" should not exist
|
||||
And as "Alice" folder "firstFolder" should not exist
|
||||
|
||||
|
||||
Scenario: copy file from personal to project space
|
||||
@@ -155,3 +180,11 @@ Feature: create a resources using collaborative posixfs
|
||||
Then the command should be successful
|
||||
And for user "Brian" the content of the file "textfile.txt" of the space "Shares" should be "contentnew"
|
||||
And the public should be able to download file "textfile.txt" from the last link share with password "%public%" and the content should be "contentnew"
|
||||
|
||||
@issue-1100
|
||||
Scenario: upload and rename file
|
||||
When the administrator creates the file "test.txt" with content "content" for user "Alice" on the POSIX filesystem
|
||||
And the administrator renames the file "test.txt" to "renamed.txt" for user "Alice" on the POSIX filesystem
|
||||
And the administrator checks the attribute "user.oc.name" of file "renamed.txt" for user "Alice" on the POSIX filesystem
|
||||
Then the command output should contain "renamed.txt"
|
||||
And the content of file "/renamed.txt" for user "Alice" should be "content"
|
||||
|
||||
Reference in New Issue
Block a user