├── .gitignore ├── python ├── s3tests_boto3 │ ├── .vs │ │ ├── PythonSettings.json │ │ ├── ProjectSettings.json │ │ ├── slnx.sqlite │ │ ├── s3tests_boto3 │ │ │ └── v16 │ │ │ │ └── .suo │ │ └── VSWorkspaceState.json │ ├── __init__.py │ └── functional │ │ ├── test_utils.py │ │ ├── policy.py │ │ ├── utils.py │ │ └── rgw_interactive.py ├── requirements.txt ├── .gitignore ├── setup.py ├── README.md ├── sample.conf ├── README.rst ├── run_test.sh └── bootstrap ├── java ├── src │ ├── test │ │ ├── resources │ │ │ ├── junit-platform.properties │ │ │ └── logback.xml │ │ └── java │ │ │ └── org │ │ │ └── example │ │ │ └── s3tests │ │ │ ├── LocalTest.java │ │ │ ├── Payment.java │ │ │ ├── KsanApiTest.java │ │ │ ├── Accelerate.java │ │ │ ├── Notification.java │ │ │ ├── Website.java │ │ │ ├── DeleteBucket.java │ │ │ ├── Cors.java │ │ │ ├── Ownership.java │ │ │ ├── Analytics.java │ │ │ ├── Access.java │ │ │ ├── Replication.java │ │ │ ├── ListBuckets.java │ │ │ ├── DeleteObjects.java │ │ │ ├── Logging.java │ │ │ ├── Metrics.java │ │ │ └── CSE.java │ └── main │ │ ├── resources │ │ └── logback.xml │ │ └── java │ │ └── org │ │ └── example │ │ ├── Data │ │ ├── RangeSet.java │ │ ├── FormFile.java │ │ ├── MyResult.java │ │ ├── MultipartUploadData.java │ │ ├── ObjectVersionsData.java │ │ ├── ObjectData.java │ │ ├── UserData.java │ │ ├── ObjectDataV2.java │ │ └── AES256.java │ │ ├── auth │ │ ├── AWS2SignerBase.java │ │ ├── AWS4SignerForAuthorizationHeader.java │ │ └── AWS4SignerForQueryParameterAuth.java │ │ ├── test │ │ ├── KMS.java │ │ ├── KsanApiTest.java │ │ ├── Localtest.java │ │ ├── Payment.java │ │ ├── Website.java │ │ ├── DeleteBucket.java │ │ └── Accelerate.java │ │ ├── testV2 │ │ ├── KMS.java │ │ ├── Payment.java │ │ ├── DeleteBucket.java │ │ ├── Website.java │ │ └── Accelerate.java │ │ └── Utility │ │ ├── S3ChecksumAlgorithm.java │ │ └── CheckSum.java ├── start.sh ├── .gitignore ├── start.bat ├── start-function.bat ├── start-function.sh ├── jar-with-dependencies.xml ├── sample.ini ├── README.md └── merge_junit_results.py ├── dotnet ├── .editorconfig ├── .gitignore ├── Data │ ├── FormFile.cs │ ├── AssertX.cs │ ├── UserData.cs │ ├── S3Headers.cs │ ├── MyResult.cs │ ├── SSECustomerKey.cs │ ├── MultipartUploadData.cs │ ├── ObjectVersionsData.cs │ ├── ObjectData.cs │ ├── S3Config.cs │ └── MainData.cs ├── Signers │ ├── ErrorResponse.cs │ └── S3Exception.cs ├── sample.ini ├── README.md ├── s3tests.sln ├── Test │ ├── DeleteBucket.cs │ ├── AES256.cs │ ├── ListObjectsVersions.cs │ ├── Website.cs │ ├── ListBuckets.cs │ └── Accelerate.cs └── s3tests.csproj ├── Utils ├── ReplicationTest │ ├── .gitignore │ ├── S3ChecksumAlgorithm.cs │ ├── sample.ini │ ├── LogConfig.xml │ ├── proxy.ini │ ├── ksan.ini │ ├── gw.ini │ ├── UserData.cs │ ├── BucketData.cs │ ├── ReplicationTest.sln │ ├── DBConfig.cs │ ├── ReplicationTest.csproj │ ├── README.md │ ├── Program.cs │ └── Utility.cs └── xmlParser │ ├── run.ps1 │ ├── upload.ps1 │ ├── config.yml │ ├── src │ └── com │ │ └── pspace │ │ ├── jenkins │ │ ├── JenkinsConfig.java │ │ ├── TestResult.java │ │ ├── DbConfig.java │ │ ├── Properties.java │ │ ├── PlatformInfo.java │ │ ├── XmlParser.java │ │ ├── TestCase.java │ │ ├── TestSuite.java │ │ └── DBManager.java │ │ └── main │ │ ├── MainConfig.java │ │ └── Main.java │ ├── .gitignore │ ├── log4j2.xml │ └── jar-with-dependencies.xml ├── .gitmodules ├── README.md └── LICENSE2 /.gitignore: -------------------------------------------------------------------------------- 1 | *.svn 2 | *.suo 3 | *.vs 4 | suwon* 5 | -------------------------------------------------------------------------------- /python/s3tests_boto3/.vs/PythonSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "TestFramework": "Pytest" 3 | } -------------------------------------------------------------------------------- /python/s3tests_boto3/.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /java/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.execution.parallel.enabled = true 2 | -------------------------------------------------------------------------------- /dotnet/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE1006: 명명 스타일 4 | dotnet_diagnostic.IDE1006.severity = none 5 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | .vscode/ 4 | config.ini 5 | gw2gw.ini 6 | gw2proxy.ini 7 | *.sh 8 | *.ps1 -------------------------------------------------------------------------------- /Utils/xmlParser/run.ps1: -------------------------------------------------------------------------------- 1 | clear 2 | mvn clean package 3 | java -jar target/xmlReportParser -f "2025-05-28_10-45_Manual.xml" -------------------------------------------------------------------------------- /dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | bin/ 3 | obj/ 4 | *.bat 5 | s3tests_* 6 | awstests.ini 7 | *.sh 8 | suwon* 9 | TestResults/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "xunit-to-html"] 2 | path = xunit-to-html 3 | url = https://github.com/Zir0-93/xunit-to-html.git 4 | -------------------------------------------------------------------------------- /python/s3tests_boto3/.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinistor/ksantest/HEAD/python/s3tests_boto3/.vs/slnx.sqlite -------------------------------------------------------------------------------- /Utils/xmlParser/upload.ps1: -------------------------------------------------------------------------------- 1 | clear 2 | mvn clean package 3 | scp target/xmlReportParser root@192.168.11.245:/DOCKER/utils/xml_report_parser/ -------------------------------------------------------------------------------- /python/s3tests_boto3/.vs/s3tests_boto3/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinistor/ksantest/HEAD/python/s3tests_boto3/.vs/s3tests_boto3/v16/.suo -------------------------------------------------------------------------------- /Utils/xmlParser/config.yml: -------------------------------------------------------------------------------- 1 | db: 2 | host: 192.168.11.245 3 | port: 3306 4 | database: jenkins 5 | user: jenkins 6 | password: jenkins123 7 | jenkins: 8 | url: http://192.168.11.245:8080 -------------------------------------------------------------------------------- /python/s3tests_boto3/.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "", 4 | "\\functional" 5 | ], 6 | "SelectedNode": "\\functional\\__init__.py", 7 | "PreviewInSolutionExplorer": false 8 | } -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/JenkinsConfig.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Setter 7 | @Getter 8 | public class JenkinsConfig { 9 | private String url; 10 | } -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | PyYAML 2 | nose >=1.0.0 3 | boto >=2.6.0 4 | boto3 >=1.0.0 5 | munch >=2.0.0 6 | # 0.14 switches to libev, that means bootstrap needs to change too 7 | gevent >=1.0 8 | isodate >=0.4.4 9 | requests >=2.23.0 10 | pytz >=2011k 11 | httplib2 12 | lxml 13 | -------------------------------------------------------------------------------- /java/start.sh: -------------------------------------------------------------------------------- 1 | clear 2 | export S3TESTS_INI=config.ini 3 | mvn clean 4 | mvn test surefire-report:report 5 | python ./merge_junit_results.py ./target/results/*.xml > xunit-to-html-master/Result_java.xml 6 | cd xunit-to-html-master 7 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl -------------------------------------------------------------------------------- /Utils/xmlParser/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .svn/ 3 | junit-merger/ 4 | .project 5 | .settings/ 6 | s3tests_* 7 | s3tests-* 8 | .vscode/ 9 | .factorypath 10 | logs/ 11 | awstests.ini 12 | s3tests-* 13 | s3tests.ini 14 | run_jenkins* 15 | .classpath 16 | junit-merger.exe 17 | xunit-to-html-master/ 18 | suwon* 19 | bundang* 20 | allinone* 21 | config.ini -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .svn/ 3 | junit-merger/ 4 | .settings/ 5 | .project 6 | .vscode/ 7 | xunit-to-html-master/ 8 | logs/ 9 | scripts/ 10 | s3tests_* 11 | s3tests-* 12 | .factorypath 13 | awstests.ini 14 | s3tests-* 15 | s3tests.ini 16 | run_jenkins* 17 | .classpath 18 | junit-merger.exe 19 | suwon* 20 | bundang* 21 | allinone* 22 | config.ini -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/TestResult.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | @Getter 8 | @Setter 9 | @XmlAccessorType(XmlAccessType.FIELD) 10 | public class TestResult { 11 | @XmlAttribute 12 | private String type; 13 | 14 | @XmlAttribute 15 | private String message; 16 | 17 | @XmlValue 18 | private String content; 19 | } -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .#* 3 | ## the next line needs to start with a backslash to avoid looking like 4 | ## a comment 5 | \#*# 6 | .*.swp 7 | 8 | *.pyc 9 | *.pyo 10 | 11 | /*.egg-info 12 | /virtualenv 13 | s3test/ 14 | s3tests/ 15 | .pytest_cache/ 16 | __pycache__/ 17 | results/ 18 | 19 | config.yaml 20 | 21 | s3tests_227.conf 22 | s3tests_229.conf 23 | s3tests_gw.conf 24 | s3tests_s3proxy.conf 25 | *.sh 26 | test_s3_backup.py 27 | awstests.conf -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/DbConfig.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Setter 7 | @Getter 8 | public class DbConfig { 9 | private String host; 10 | private int port; 11 | private String database; 12 | private String user; 13 | private String password; 14 | 15 | public String getConnectionUrl() { 16 | return String.format("jdbc:mariadb://%s:%d/%s", host, port, database); 17 | } 18 | } -------------------------------------------------------------------------------- /Utils/xmlParser/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread{5}][%logger{10}.%method:%line] : %msg%n 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /java/start.bat: -------------------------------------------------------------------------------- 1 | if "%1" NEQ "" ( 2 | SET INI_FILE=%1.ini 3 | ) else ( 4 | SET INI_FILE=config.ini 5 | ) 6 | 7 | cls 8 | del xunit-to-html-master\Result_java.html 9 | del xunit-to-html-master\Result_java.xml 10 | call mvn clean 11 | call mvn test surefire-report:report -Ds3tests.ini=%INI_FILE% 12 | python merge_junit_results.py target\results\*.xml > xunit-to-html-master\Result_java.xml 13 | cd xunit-to-html-master 14 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 15 | start Result_java.html 16 | -------------------------------------------------------------------------------- /python/s3tests_boto3/__init__.py: -------------------------------------------------------------------------------- 1 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 2 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 3 | #the GNU General Public License as published by the Free Software Foundation, either version 4 | #3 of the License. See LICENSE for details 5 | 6 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 7 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 8 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 9 | -------------------------------------------------------------------------------- /java/start-function.bat: -------------------------------------------------------------------------------- 1 | if "%3"=="" ( 2 | echo "Usage: start-function.bat " 3 | exit /b 4 | ) 5 | 6 | cls 7 | SET S3TESTS_INI=%1.ini 8 | del xunit-to-html-master\Result_java.html 9 | del xunit-to-html-master\Result_java.xml 10 | call mvn clean 11 | call mvn test surefire-report:report -Dtest=%2#%3 12 | .\junit-merger.exe target/results > xunit-to-html-master\Result_java.xml 13 | cd xunit-to-html-master 14 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 15 | start Result_java.html -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/Properties.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import java.util.List; 7 | 8 | @Getter 9 | @Setter 10 | @XmlAccessorType(XmlAccessType.FIELD) 11 | public class Properties { 12 | @XmlElement(name = "property") 13 | private List properties; 14 | } 15 | 16 | @Getter 17 | @Setter 18 | @XmlAccessorType(XmlAccessType.FIELD) 19 | class Property { 20 | @XmlAttribute 21 | private String name; 22 | 23 | @XmlAttribute 24 | private String value; 25 | } -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/PlatformInfo.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class PlatformInfo { 7 | private final String platform; 8 | private final String os; 9 | private final String gateway; 10 | private final String envType; 11 | private final String triggerType; 12 | 13 | public PlatformInfo(String platform, String os, String gateway, String envType, String triggerType) { 14 | this.platform = platform; 15 | this.os = os; 16 | this.gateway = gateway; 17 | this.envType = envType; 18 | this.triggerType = triggerType; 19 | } 20 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KSAN TEST 2 | 3 | KSAN 시스템의 기능 및 성능을 검증하는 도구를 제공합니다. 4 | 5 | ## [S3 compatibility test for Java](https://github.com/infinistor/ksantest/tree/master/java) 6 | 7 | ## [S3 compatibility test for Python](https://github.com/infinistor/ksantest/tree/master/python) 8 | 9 | ## [S3 compatibility test for .Net Core](https://github.com/infinistor/ksantest/tree/master/C%23/Core) 10 | 11 | ## [S3 compatibility test for .Net Framework](https://github.com/infinistor/ksantest/tree/master/C%23/Framework) 12 | 13 | ## [S3 Replication test for .Net Core](https://github.com/infinistor/ksantest/tree/master/C%23/ReplicationTest) -------------------------------------------------------------------------------- /java/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread{5}][%logger{10}.%method:%line] : %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /java/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread{5}][%logger{10}.%method:%line] : %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/S3ChecksumAlgorithm.cs: -------------------------------------------------------------------------------- 1 | namespace ReplicationTest 2 | { 3 | public enum S3ChecksumAlgorithm 4 | { 5 | None, 6 | CRC32, 7 | CRC32C, 8 | CRC64NVME, 9 | SHA1, 10 | SHA256, 11 | } 12 | 13 | public static class S3ChecksumAlgorithmExtensions 14 | { 15 | public static string ToName(this S3ChecksumAlgorithm algorithm) => algorithm switch 16 | { 17 | S3ChecksumAlgorithm.CRC32 => "CRC32", 18 | S3ChecksumAlgorithm.CRC32C => "CRC32C", 19 | S3ChecksumAlgorithm.CRC64NVME => "CRC64NVME", 20 | S3ChecksumAlgorithm.SHA1 => "SHA1", 21 | S3ChecksumAlgorithm.SHA256 => "SHA256", 22 | _ => "None", 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /java/start-function.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$3" ]; then 4 | echo "Usage: start-function.sh " 5 | exit 1 6 | fi 7 | 8 | clear 9 | export S3TESTS_INI="$1" 10 | rm -f xunit-to-html-master/Result_java.html 11 | rm -f xunit-to-html-master/Result_java.xml 12 | mvn clean 13 | mvn test surefire-report:report -Dtest="$2#$3" 14 | ./junit-merger.exe target/results > xunit-to-html-master/Result_java.xml 15 | cd xunit-to-html-master 16 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 17 | xdg-open Result_java.html 2>/dev/null || open Result_java.html 2>/dev/null || echo "Please open Result_java.html manually" 18 | 19 | -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/main/MainConfig.java: -------------------------------------------------------------------------------- 1 | package com.pspace.main; 2 | 3 | import com.pspace.jenkins.DbConfig; 4 | import com.pspace.jenkins.JenkinsConfig; 5 | import lombok.Setter; 6 | import lombok.Getter; 7 | import org.yaml.snakeyaml.Yaml; 8 | 9 | import java.io.FileInputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | 13 | @Setter 14 | @Getter 15 | public class MainConfig { 16 | private DbConfig db; 17 | private JenkinsConfig jenkins; 18 | 19 | public static MainConfig load(String configFile) throws IOException { 20 | try (InputStream inputStream = new FileInputStream(configFile)) { 21 | return new Yaml().loadAs(inputStream, MainConfig.class); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /dotnet/Data/FormFile.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | namespace s3tests 12 | { 13 | public class FormFile 14 | { 15 | public string Name { get; set; } 16 | public string ContentType { get; set; } 17 | public string Body { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/sample.ini: -------------------------------------------------------------------------------- 1 | [Global] 2 | # replication이 완료될때까지 대기하는 시간 (단위 : sec) 3 | Delay = 30 4 | # 버전 정보 동기화 체크 여부 5 | CheckVersionId = true 6 | # 기본 설정 버킷 명 7 | NormalBucket = source-normal 8 | # SSE-S3 설정 버킷 명 9 | EncryptionBucket = source-encryption 10 | # 테스트용 생성 버킷 접두어 11 | TargetBucketPrefix = test- 12 | #Test Option 13 | # 0 = ALL 14 | # 1 = Local Only 15 | # 2 = Another Only 16 | TestOption = 0 17 | # SSL Option 18 | # 0 = ALL 19 | # 1 = Http Only 20 | # 2 = Https Only 21 | SSL = 0 22 | 23 | # 원본 유저 및 시스템 24 | [Main User] 25 | URL = 0.0.0.0 26 | Port = 80 27 | SSLPort = 443 28 | AccessKey = accesskey 29 | SecretKey = secretkey 30 | 31 | # 대상 유저 및 시스템 32 | [Alt User] 33 | URL = 0.0.0.0 34 | Port = 80 35 | SSLPort = 443 36 | RegionName = 37 | AccessKey = accesskey 38 | SecretKey = secretkey -------------------------------------------------------------------------------- /Utils/ReplicationTest/LogConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /dotnet/Signers/ErrorResponse.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License.See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Xml.Serialization; 12 | 13 | namespace s3tests.Signers 14 | { 15 | [XmlRoot(ElementName = "Error")] 16 | public class ErrorResponse 17 | { 18 | public string Code { get; set; } 19 | public string Message { get; set; } 20 | public string RequestId { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/RangeSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | public class RangeSet { 14 | public int start; 15 | public int end; 16 | public int length; 17 | 18 | public RangeSet(int start, int length) 19 | { 20 | this.start = start; 21 | this.length = length; 22 | end = start + length; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/proxy.ini: -------------------------------------------------------------------------------- 1 | [Global] 2 | # replication이 완료될때까지 대기하는 시간 (단위 : sec) 3 | Delay = 30 4 | # 버전 정보 동기화 체크 여부 5 | CheckVersionId = true 6 | # Etag 값 비교 여부 7 | CheckEtag = false 8 | # 기본 설정 버킷 명 9 | NormalBucket = source-normal 10 | # SSE-S3 설정 버킷 명 11 | EncryptionBucket = source-encryption 12 | # 테스트용 생성 버킷 접두어 13 | TargetBucketPrefix = test- 14 | #Test Option 15 | # 0 = ALL 16 | # 1 = Local Only 17 | # 2 = Another Only 18 | TestOption = 1 19 | # SSL Option 20 | # 0 = ALL 21 | # 1 = Http Only 22 | # 2 = Https Only 23 | SSL = 1 24 | 25 | [Main User] 26 | URL = 192.168.11.227 27 | Port = 8080 28 | SSLPort = 8443 29 | RegionName = proxy-all-1 30 | AccessKey = 3ea60d0a142243c70eb5 31 | SecretKey = 096461dfb4df1d96736565bb 32 | 33 | [Alt User] 34 | URL = 192.168.11.229 35 | Port = 8080 36 | SSLPort = 8443 37 | RegionName = gw-all-1 38 | AccessKey = a909a16f91799ed78676 39 | SecretKey = 1c7923dda67c34ce0bc10473 40 | -------------------------------------------------------------------------------- /dotnet/Data/AssertX.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace s3tests.Data 4 | { 5 | public class MyEqualException : Xunit.Sdk.XunitException 6 | { 7 | public string UserMessage { get; } 8 | 9 | public MyEqualException(object expected, object actual, string userMessage) 10 | : base($"{userMessage}\nExpected: {expected}\nActual: {actual}") 11 | { 12 | UserMessage = userMessage; 13 | } 14 | } 15 | 16 | public static class AssertX 17 | { 18 | public static void Equal(T expected, T actual, string userMessage) 19 | { 20 | bool areEqual; 21 | 22 | if (expected == null && actual == null) 23 | areEqual = true; 24 | else if (expected == null || actual == null) 25 | areEqual = false; 26 | else 27 | areEqual = EqualityComparer.Default.Equals(expected, actual); 28 | 29 | if (!areEqual) 30 | throw new MyEqualException(expected, actual, userMessage); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/auth/AWS2SignerBase.java: -------------------------------------------------------------------------------- 1 | package org.example.auth; 2 | 3 | import static org.junit.jupiter.api.Assertions.fail; 4 | 5 | import java.security.InvalidKeyException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.util.Base64; 8 | 9 | import javax.crypto.Mac; 10 | import javax.crypto.spec.SecretKeySpec; 11 | 12 | public class AWS2SignerBase { 13 | 14 | public static String GetBase64EncodedSHA1Hash(String Policy, String SecretKey) { 15 | var signingKey = new SecretKeySpec(SecretKey.getBytes(), "HmacSHA1"); 16 | Mac mac; 17 | try { 18 | mac = Mac.getInstance("HmacSHA1"); 19 | mac.init(signingKey); 20 | } catch (NoSuchAlgorithmException e) { 21 | fail(e.getMessage()); 22 | return ""; 23 | } catch (InvalidKeyException e) { 24 | fail(e.getMessage()); 25 | return ""; 26 | } 27 | 28 | var encoder = Base64.getEncoder(); 29 | return encoder.encodeToString((mac.doFinal(Policy.getBytes()))); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/ksan.ini: -------------------------------------------------------------------------------- 1 | [Global] 2 | # replication이 완료될때까지 대기하는 시간 (단위 : sec) 3 | Delay = 30 4 | # 버전 정보 동기화 체크 여부 5 | CheckVersionId = true 6 | # 기본 설정 버킷 명 7 | NormalBucket = source-normal 8 | # SSE-S3 설정 버킷 명 9 | EncryptionBucket = source-encryption 10 | # 테스트용 생성 버킷 접두어 11 | TargetBucketPrefix = test- 12 | #Test Option 13 | # 0 = ALL 14 | # 1 = Local Only 15 | # 2 = Another Only 16 | TestOption = 0 17 | # SSL Option 18 | # 0 = ALL 19 | # 1 = Http Only 20 | # 2 = Https Only 21 | SSL = 0 22 | 23 | [DB] 24 | host = 192.168.11.245 25 | port = 3306 26 | name = test_db 27 | username = s3tester 28 | password = qwe123 29 | 30 | [Main User] 31 | URL = 192.168.31.31 32 | Port = 7070 33 | SSLPort = 7443 34 | AccessKey = U0QAG4VYBUY4SMNY9SUO 35 | SecretKey = Ytnck7L6Wg7UzwC4TWjLaT1GTcgoULsi1Kh8OoMN 36 | 37 | [Alt User] 38 | URL = 192.168.31.31 39 | Port = 7070 40 | SSLPort = 7443 41 | RegionName = kr-ksan-1 42 | AccessKey = U0QAG4VYBUY4SMNY9SUO 43 | SecretKey = Ytnck7L6Wg7UzwC4TWjLaT1GTcgoULsi1Kh8OoMN -------------------------------------------------------------------------------- /python/s3tests_boto3/functional/test_utils.py: -------------------------------------------------------------------------------- 1 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 2 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 3 | #the GNU General Public License as published by the Free Software Foundation, either version 4 | #3 of the License. See LICENSE for details 5 | 6 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 7 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 8 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 9 | from nose.tools import eq_ as eq 10 | 11 | from . import utils 12 | 13 | def test_generate(): 14 | FIVE_MB = 5 * 1024 * 1024 15 | eq(len(''.join(utils.generate_random(0))), 0) 16 | eq(len(''.join(utils.generate_random(1))), 1) 17 | eq(len(''.join(utils.generate_random(FIVE_MB - 1))), FIVE_MB - 1) 18 | eq(len(''.join(utils.generate_random(FIVE_MB))), FIVE_MB) 19 | eq(len(''.join(utils.generate_random(FIVE_MB + 1))), FIVE_MB + 1) 20 | -------------------------------------------------------------------------------- /dotnet/Signers/S3Exception.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License.See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System; 12 | using Amazon.Runtime.Internal; 13 | 14 | namespace s3tests.Signers 15 | { 16 | public class S3Exception : Exception 17 | { 18 | public ErrorResponse Response { get; set; } 19 | public S3Exception() : base() 20 | { 21 | Response = new ErrorResponse(); 22 | } 23 | 24 | public S3Exception(ErrorResponse Response, Exception innerException) : base(Response.Message, innerException) 25 | { 26 | this.Response = Response; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/XmlParser.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import jakarta.xml.bind.JAXBContext; 6 | import java.io.File; 7 | 8 | public class XmlParser { 9 | private static final Logger log = LoggerFactory.getLogger(XmlParser.class); 10 | private final String fileName; 11 | private TestSuite testSuite; 12 | 13 | public XmlParser(String fileName) { 14 | this.fileName = fileName; 15 | } 16 | 17 | public boolean read() { 18 | try { 19 | var context = JAXBContext.newInstance(TestSuite.class); 20 | var unmarshaller = context.createUnmarshaller(); 21 | testSuite = (TestSuite) unmarshaller.unmarshal(new File(fileName)); 22 | if (testSuite != null) { 23 | testSuite.setSourceFile(fileName); 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | log.error("Error parsing XML file: " + fileName, e); 28 | return false; 29 | } 30 | } 31 | 32 | public TestSuite getTestSuite() { 33 | return testSuite; 34 | } 35 | } -------------------------------------------------------------------------------- /Utils/ReplicationTest/gw.ini: -------------------------------------------------------------------------------- 1 | [Global] 2 | # replication이 완료될때까지 대기하는 시간 (단위 : sec) 3 | Delay = 30 4 | # 버전 정보 동기화 체크 여부 5 | CheckVersionId = true 6 | # Etag 값 비교 여부 7 | CheckEtag = false 8 | # 기본 설정 버킷 명 9 | NormalBucket = source-normal 10 | # SSE-S3 설정 버킷 명 11 | EncryptionBucket = source-encryption 12 | # 테스트용 생성 버킷 접두어 13 | TargetBucketPrefix = test- 14 | #Test Option 15 | # 0 = ALL 16 | # 1 = Local Only 17 | # 2 = Another Only 18 | TestOption = 1 19 | # SSL Option 20 | # 0 = ALL 21 | # 1 = Http Only 22 | # 2 = Https Only 23 | SSL = 1 24 | 25 | [DB] 26 | Host = 192.168.11.245 27 | Port = 3306 28 | DBName = test_db 29 | TableName = gw-replication-test 30 | UserName = root 31 | Password = qwe123 32 | 33 | [Main User] 34 | URL = 192.168.11.229 35 | Port = 8080 36 | SSLPort = 8443 37 | RegionName = gw-all-1 38 | AccessKey = infinistor 39 | SecretKey = infinistor 40 | 41 | [Alt User] 42 | URL = 192.168.11.227 43 | Port = 8080 44 | SSLPort = 8443 45 | RegionName = proxy-all-1 46 | AccessKey = 3ea60d0a142243c70eb5 47 | SecretKey = 096461dfb4df1d96736565bb 48 | -------------------------------------------------------------------------------- /dotnet/Data/UserData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | namespace s3tests 12 | { 13 | public class UserData 14 | { 15 | public string DisplayName { set; get; } 16 | public string UserId { set; get; } 17 | public string AccessKey { set; get; } 18 | public string SecretKey { set; get; } 19 | 20 | public UserData() 21 | { 22 | Init(); 23 | } 24 | 25 | public void Init() 26 | { 27 | DisplayName = string.Empty; 28 | UserId = string.Empty; 29 | AccessKey = string.Empty; 30 | SecretKey = string.Empty; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dotnet/Data/S3Headers.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Globalization; 12 | 13 | namespace s3tests 14 | { 15 | public class S3Headers 16 | { 17 | private const string AWSHeader = "x-amz-meta-"; 18 | 19 | public const string CacheControl = AWSHeader + "cache-control"; 20 | public const string Expires = AWSHeader + "expires"; 21 | 22 | 23 | public const string TimeFormat = "r"; 24 | public const string StrTimeCulture = "en-US"; 25 | public static CultureInfo TimeCulture = CultureInfo.CreateSpecificCulture(StrTimeCulture); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dotnet/sample.ini: -------------------------------------------------------------------------------- 1 | [Default] 2 | 3 | [S3] 4 | # URL 설정 5 | URL = 0.0.0.0 6 | 7 | # Http Port 설정 8 | Port = 80 9 | 10 | # Https Port 설정 11 | SSLPort = 443 12 | 13 | ## Signature Version.(2 or 4) 14 | SignatureVersion = 2 15 | 16 | # 리전 17 | RegionName = ap-northeast-2 18 | 19 | [Fixtures] 20 | # 기본적인 통신을 http, https중에서 선택 21 | # true : https 22 | # false : http 23 | IsSecure = False 24 | 25 | ## 테스트 버킷 생성시 접두어 설정 26 | ## {random}은 15자리의 랜덤한 문자열로 자동 생성 27 | ## 버킷의 길이제한인 63자리가 넘을경우 63자리까지 잘라서 사용하도록 동작 28 | BucketPrefix = s3-test-core-{random}- 29 | 30 | # KMS(테스트 케이스가 존재하지 않음) 31 | KMS = 32 | 33 | [Main User] 34 | # 유저명 35 | DisplayName = user1 36 | 37 | # 유저 Id 38 | UserId = 1 39 | 40 | # 유저 Email 41 | Email = user1@test.co.kr 42 | 43 | # AWS Access Key 44 | AccessKey = accesskey 45 | 46 | # AWS Secret Key 47 | SecretKey = secretkey 48 | 49 | [Alt User] 50 | # 유저명 51 | DisplayName = user2 52 | 53 | # 유저 Id 54 | UserId = 2 55 | 56 | # 유저 Email 57 | Email = user2@test.co.kr 58 | 59 | # AWS Access Key 60 | AccessKey = accesskey 61 | 62 | # AWS Secret Key 63 | SecretKey = secretkey -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/KMS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import org.junit.Test; 14 | import org.junit.jupiter.api.Tag; 15 | 16 | public class KMS { 17 | 18 | @org.junit.jupiter.api.BeforeAll 19 | public static void beforeAll() 20 | { 21 | System.out.println("KMS Start"); 22 | } 23 | 24 | @org.junit.jupiter.api.AfterAll 25 | public static void afterAll() 26 | { 27 | System.out.println("KMS End"); 28 | } 29 | 30 | @Test 31 | @Tag("PutGet") 32 | public void testSseKmsEncryptedTransfer1b(){ 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/UserData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Text.Json; 12 | 13 | namespace ReplicationTest 14 | { 15 | class UserData 16 | { 17 | public string URL { get; set; } 18 | public int Port { get; set; } 19 | public int SSLPort { get; set; } 20 | public string AccessKey { get; set; } 21 | public string SecretKey { get; set; } 22 | public string RegionName { get; set; } 23 | 24 | public bool IsRegion { get => !string.IsNullOrEmpty(RegionName); } 25 | 26 | public override string ToString() => $"UserData : {JsonSerializer.Serialize(this)}"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/testV2/KMS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.testV2; 12 | 13 | import org.junit.Test; 14 | import org.junit.jupiter.api.Tag; 15 | 16 | public class KMS { 17 | 18 | @org.junit.jupiter.api.BeforeAll 19 | public static void beforeAll() 20 | { 21 | System.out.println("KMS V2 Start"); 22 | } 23 | 24 | @org.junit.jupiter.api.AfterAll 25 | public static void afterAll() 26 | { 27 | System.out.println("KMS V2 End"); 28 | } 29 | 30 | @Test 31 | @Tag("PutGet") 32 | public void testSseKmsEncryptedTransfer1b(){ 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | #the GNU General Public License as published by the Free Software Foundation, either version 5 | #3 of the License. See LICENSE for details 6 | 7 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | from setuptools import setup, find_packages 11 | 12 | setup( 13 | name='s3tests', 14 | version='0.0.1', 15 | packages=find_packages(), 16 | 17 | author='Tommi Virtanen', 18 | author_email='tommi.virtanen@dreamhost.com', 19 | description='Unofficial Amazon AWS S3 compatibility tests', 20 | license='MIT', 21 | keywords='s3 web testing', 22 | 23 | install_requires=[ 24 | 'boto >=2.0b4', 25 | 'boto3 >=1.0.0', 26 | 'PyYAML', 27 | 'munch >=2.0.0', 28 | 'gevent >=1.0', 29 | 'isodate >=0.4.4', 30 | ], 31 | ) 32 | -------------------------------------------------------------------------------- /dotnet/Data/MyResult.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Net; 12 | 13 | namespace s3tests 14 | { 15 | public class MyResult 16 | { 17 | public HttpStatusCode StatusCode { get; set; } 18 | public string ErrorCode { get; set; } 19 | public string Message { get; set; } 20 | public string URL { get; set; } 21 | public WebHeaderCollection Headers { get; set; } 22 | 23 | public MyResult() 24 | { 25 | Init(); 26 | } 27 | public void Init() 28 | { 29 | StatusCode = HttpStatusCode.OK; 30 | ErrorCode = string.Empty; 31 | Message = string.Empty; 32 | URL = string.Empty; 33 | Headers = null; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /dotnet/Data/SSECustomerKey.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3; 12 | 13 | namespace s3tests 14 | { 15 | public class SSECustomerKey 16 | { 17 | public ServerSideEncryptionCustomerMethod Method; 18 | public string ProvidedKey; 19 | public string MD5; 20 | 21 | public SSECustomerKey() 22 | { 23 | Method = ServerSideEncryptionCustomerMethod.None; 24 | ProvidedKey = ""; 25 | MD5 = ""; 26 | } 27 | 28 | public SSECustomerKey(ServerSideEncryptionCustomerMethod Method, string ProviderKey, string MD5) 29 | { 30 | this.Method = Method; 31 | this.ProvidedKey = ProviderKey; 32 | this.MD5 = MD5; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/LocalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | class LocalTest { 19 | 20 | // org.example.test.LocalTest test = new org.example.test.LocalTest(); 21 | // org.example.testV2.LocalTest testV2 = new org.example.testV2.LocalTest(); 22 | 23 | // /** 24 | // * 테스트 정리 작업 수행 25 | // * 26 | // * @param testInfo 테스트 정보 27 | // */ 28 | // @AfterEach 29 | // void clear(TestInfo testInfo) { 30 | // test.clear(testInfo); 31 | // testV2.clear(testInfo); 32 | // } 33 | } 34 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/BucketData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | namespace ReplicationTest 12 | { 13 | class BucketData 14 | { 15 | public string BucketName { get; set; } 16 | public bool Prefix { get; set; } 17 | public bool DeleteMarker { get; set; } 18 | public bool Encryption { get; set; } 19 | public bool Create { get; set; } 20 | public bool Tag { get; set; } 21 | 22 | public BucketData() 23 | { 24 | Init(); 25 | } 26 | 27 | public void Init() 28 | { 29 | BucketName = ""; 30 | Prefix = false; 31 | DeleteMarker = false; 32 | Encryption = false; 33 | Create = false; 34 | Tag = false; 35 | } 36 | 37 | public bool Filtering { get { return Prefix || Tag; } } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/ReplicationTest.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30804.86 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReplicationTest", "ReplicationTest.csproj", "{AEBF4C6E-F45C-432C-9A64-A74DA62C251D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {AEBF4C6E-F45C-432C-9A64-A74DA62C251D}.Debug|Any CPU.ActiveCfg = Release|Any CPU 15 | {AEBF4C6E-F45C-432C-9A64-A74DA62C251D}.Debug|Any CPU.Build.0 = Release|Any CPU 16 | {AEBF4C6E-F45C-432C-9A64-A74DA62C251D}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {AEBF4C6E-F45C-432C-9A64-A74DA62C251D}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {473192C6-FB09-4F2D-BBC1-F4AF159BF818} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /LICENSE2: -------------------------------------------------------------------------------- 1 | Parts of source code to python test. Associated license is bellow. 2 | https://github.com/ceph/s3-tests 3 | 4 | Copyright (c) 2011 New Dream Network, LLC 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /dotnet/README.md: -------------------------------------------------------------------------------- 1 | # S3 compatibility test for .Net Core 2 | 3 | 이 테스트는 아마존에서 제공하는 S3 Api를 사용하여 S3 호환 프로그램에 대한 기능점검 프로그램입니다. 4 | 5 | 별도의 유틸을 이용하여 보기 쉽게 결과물을 출력하는 기능을 포함하고 있습니다. 6 | 7 | ## 구동환경 8 | 9 | * .Net Core : 7 이상 10 | 11 | ## How to Build 12 | 13 | ### dotnet 설치 14 | 15 | #### Window 10 16 | - 설치파일 링크 : [Link](https://dotnet.microsoft.com/en-us/download/dotnet/3.1) 17 | 18 | #### CentOS 7 19 | ``` 20 | sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm 21 | sudo yum install -y dotnet-sdk-3.1 22 | ``` 23 | 24 | ### Build 25 | ``` shell 26 | dotnet build -c Release 27 | ``` 28 | 29 | ## 테스트 방법 30 | 31 | ### 테스트 실행 32 | ``` ps1 33 | #설정파일 경로 34 | SET S3TESTS_INI=sample.ini 35 | dotnet test s3tests.dll --test-adapter-path:. --nologo --logger "junit;" 36 | ``` 37 | ### 레포트 출력 38 | ```ps1 39 | COPY TestResults\TestResults.xml ..\..\..\..\..\xunit-to-html\result_netcore.xml 40 | cd ..\..\..\..\..\xunit-to-html\ 41 | java -jar saxon9he.jar -o:result_netcore.html -s:result_netcore.xml -xsl:xunit_to_html.xsl 42 | start result_netcore.html 43 | ``` 44 | ## 테스트 결과 레포트 확인 45 | 46 | - 테스트 결과 레포트는 [링크](https://github.com/Zir0-93/xunit-to-html)를 사용하여 작성했습니다. 47 | - 테스트 결과는 **../xunit-to-html-master/result_netcore.html**로 확인 가능합니다. -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/FormFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | public class FormFile { 14 | public String name; 15 | public String contentType; 16 | public String body; 17 | 18 | public FormFile(String name, String contentType, String body) { 19 | this.name = name; 20 | this.contentType = contentType; 21 | this.body = body; 22 | } 23 | 24 | public String getName() { return name; } 25 | public String getContentType() { return contentType; } 26 | public String getBody() { return body; } 27 | 28 | public void setName(String name) { this.name = name; } 29 | public void setContentType(String contentType) { this.contentType = contentType; } 30 | public void setBody(String body) { this.body = body; } 31 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/MyResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | public class MyResult { 14 | 15 | public int statusCode; 16 | public String message; 17 | public String URL; 18 | 19 | public MyResult() { 20 | Init(); 21 | } 22 | 23 | public void Init() { 24 | statusCode = -1; 25 | message = ""; 26 | URL = ""; 27 | } 28 | 29 | public String getErrorCode() { 30 | int StartIndex = message.indexOf(""); 31 | int EndIndex = message.indexOf(""); 32 | if (StartIndex != -1 && EndIndex != -1) 33 | return message.substring(StartIndex, EndIndex); 34 | return message; 35 | } 36 | 37 | public String GetContent() { 38 | return message.substring(0, message.length() - 1); 39 | } 40 | } -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Payment.java: -------------------------------------------------------------------------------- 1 | // package org.example.s3tests; 2 | 3 | // import org.junit.jupiter.api.Test; 4 | // import org.junit.jupiter.api.TestInfo; 5 | // import org.junit.jupiter.api.AfterEach; 6 | // import org.junit.jupiter.api.Tag; 7 | 8 | // class Payment { 9 | 10 | // org.example.test.Payment test = new org.example.test.Payment(); 11 | // org.example.testV2.Payment testV2 = new org.example.testV2.Payment(); 12 | 13 | // @AfterEach 14 | // void clear(TestInfo testInfo) { 15 | // test.clear(testInfo); 16 | // testV2.clear(testInfo); 17 | // } 18 | 19 | 20 | // @Test 21 | // @Tag("Put") 22 | // // 버킷 과금 설정이 가능한지 확인 23 | // void testPutBucketRequestPayment() { 24 | // test.testPutBucketRequestPayment(); 25 | // testV2.testPutBucketRequestPayment(); 26 | // } 27 | 28 | 29 | // @Test 30 | // @Tag("Get") 31 | // // 버킷 과금 설정 조회 확인 32 | // void testGetBucketRequestPayment() { 33 | // test.testGetBucketRequestPayment(); 34 | // testV2.testGetBucketRequestPayment(); 35 | // } 36 | 37 | // @Test 38 | // @Tag("Get") 39 | // // 버킷 과금 설정이 올바르게 적용되는지 확인 40 | // void testSetGetBucketRequestPayment() { 41 | // test.testSetGetBucketRequestPayment(); 42 | // testV2.testSetGetBucketRequestPayment(); 43 | // } 44 | // } 45 | -------------------------------------------------------------------------------- /java/jar-with-dependencies.xml: -------------------------------------------------------------------------------- 1 | 4 | jar-with-dependencies 5 | 6 | jar 7 | 8 | false 9 | 10 | 11 | metaInf-services 12 | 13 | 14 | 15 | 16 | / 17 | true 18 | true 19 | runtime 20 | 21 | 22 | 23 | 24 | ${project.basedir}/src/main/config 25 | / 26 | 27 | logback.xml 28 | 29 | true 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Utils/xmlParser/jar-with-dependencies.xml: -------------------------------------------------------------------------------- 1 | 4 | jar-with-dependencies 5 | 6 | jar 7 | 8 | false 9 | 10 | 11 | metaInf-services 12 | 13 | 14 | 15 | 16 | / 17 | true 18 | true 19 | runtime 20 | 21 | 22 | 23 | 24 | ${project.basedir}/src/main/config 25 | / 26 | 27 | logback.xml 28 | 29 | true 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /dotnet/Data/MultipartUploadData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3.Model; 12 | using System.Collections.Generic; 13 | 14 | namespace s3tests 15 | { 16 | public class MultipartUploadData 17 | { 18 | public string UploadId { get; set; } 19 | public List Parts { get; set; } 20 | public int NextPartNumber { get { return Parts.Count + 1; } } 21 | public string Body { get; set; } 22 | public MultipartUploadData() 23 | { 24 | UploadId = string.Empty; 25 | Body = string.Empty; 26 | Parts = new List(); 27 | } 28 | 29 | public void AddPart(int PartNumber, string Etag) => Parts.Add(new PartETag(PartNumber, Etag)); 30 | public void AddPart(PartETag Part) => Parts.Add(Part); 31 | public void AppendBody(string Body) => this.Body += Body; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dotnet/Data/ObjectVersionsData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3.Model; 12 | using System.Collections.Generic; 13 | 14 | namespace s3tests 15 | { 16 | public class ObjectVersionsData 17 | { 18 | public string bucketName { get; set; } 19 | public string Key { get; set; } 20 | public string Body { get; set; } 21 | public string ETag { get; set; } 22 | public long ContentLength { get; set; } 23 | public List TagSet { get; set; } 24 | public List VersionId { get; set; } 25 | 26 | public ObjectVersionsData() 27 | { 28 | Init(); 29 | } 30 | 31 | public void Init() 32 | { 33 | bucketName = ""; 34 | Key = ""; 35 | Body = ""; 36 | ETag = ""; 37 | ContentLength = 0; 38 | TagSet = new List(); 39 | VersionId = new List(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /dotnet/Data/ObjectData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System; 12 | 13 | namespace s3tests 14 | { 15 | public class ObjectData 16 | { 17 | public string bucketName { get; set; } 18 | public string Key { get; set; } 19 | public string DisplayName { get; set; } 20 | public string Id { get; set; } 21 | public string ETag { get; set; } 22 | public DateTime LastModified { get; set; } 23 | public long ContentLength { get; set; } 24 | public string VersionId { get; set; } 25 | 26 | public ObjectData() 27 | { 28 | Init(); 29 | } 30 | 31 | public void Init() 32 | { 33 | bucketName = null; 34 | Key = null; 35 | DisplayName = null; 36 | Id = null; 37 | ETag = null; 38 | LastModified = DateTime.UnixEpoch; 39 | ContentLength = -1; 40 | VersionId = null; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/KsanApiTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.Tag; 15 | import org.junit.jupiter.api.Test; 16 | import org.junit.jupiter.api.TestInfo; 17 | 18 | class KsanApiTest { 19 | org.example.test.KsanApiTest test = new org.example.test.KsanApiTest(); 20 | 21 | @AfterEach 22 | void clear(TestInfo testInfo) { 23 | test.clear(testInfo); 24 | } 25 | 26 | /** 27 | * 버킷에 태그 검색 설정 조회 가능한지 확인 28 | */ 29 | @Test 30 | @Tag("Get") 31 | void testGetBucketEnabledTaggingIndex() { 32 | test.testGetBucketEnabledTaggingIndex(); 33 | } 34 | 35 | /** 36 | * 버킷에 tag 검색 기능 활성화 테스트 37 | */ 38 | @Test 39 | @Tag("Put") 40 | void testPutBucketEnabledTaggingIndex() { 41 | test.testPutBucketEnabledTaggingIndex(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java/sample.ini: -------------------------------------------------------------------------------- 1 | [Default] 2 | [S3] 3 | # URL 설정 4 | URL = 0.0.0.0 5 | 6 | # Http Port 설정 7 | Port = 80 8 | 9 | # Old Http Port 설정 10 | OldPort = 8080 11 | 12 | # Https Port 설정 13 | SSLPort = 443 14 | 15 | # Signature Version.(2 or 4) 16 | SignatureVersion = 2 17 | 18 | # 리전 19 | RegionName = ap-northeast-2 20 | 21 | [Fixtures] 22 | ## 테스트 버킷 생성시 접두어 설정 23 | ## 버킷의 길이제한인 63자리가 넘을경우 63자리까지 잘라서 사용하도록 동작 24 | BucketPrefix = java- 25 | 26 | # 기본적인 통신을 http, https중에서 선택 27 | # true : https 28 | # false : http 29 | IsSecure = False 30 | 31 | [Main User] 32 | # Main DisplayName set in vstart.sh 33 | DisplayName = test1 34 | 35 | # Main UserIDname set in vstart.sh 36 | UserID = 1 37 | 38 | # Main Email set in vstart.sh 39 | Email = test1@test.co.kr 40 | 41 | # Main AWS access key 42 | AccessKey = 123123123123123 43 | 44 | # Main AWS secret key 45 | SecretKey = 123123123123123 46 | 47 | # replace with key id obtained when secret is created, or delete if KMS not tested 48 | #KMS = 01234567-89ab-cdef-0123-456789abcdef 49 | 50 | [Alt User] 51 | # alt DisplayName set in vstart.sh 52 | DisplayName = test1 53 | 54 | # alt Email set in vstart.sh 55 | Email = test1@test.co.kr 56 | 57 | # alt UserID set in vstart.sh 58 | UserID = 2 59 | 60 | # alt AWS access key set in vstart.sh 61 | AccessKey = 123123123123123 62 | 63 | # alt AWS secret key set in vstart.sh 64 | SecretKey = 123123123123123 -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/KsanApiTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import org.junit.jupiter.api.Tag; 14 | import org.junit.jupiter.api.Test; 15 | 16 | public class KsanApiTest extends TestBase { 17 | @org.junit.jupiter.api.BeforeAll 18 | public static void beforeAll() { 19 | System.out.println("KsanApiTest Start"); 20 | } 21 | 22 | @org.junit.jupiter.api.AfterAll 23 | public static void afterAll() { 24 | System.out.println("KsanApiTest End"); 25 | } 26 | 27 | @Test 28 | @Tag("Get") 29 | public void testGetBucketEnabledTaggingIndex() { 30 | var client = getClient(); 31 | var bucketName = createBucket(client); 32 | 33 | } 34 | 35 | @Test 36 | @Tag("Put") 37 | public void testPutBucketEnabledTaggingIndex() { 38 | var client = getClient(); 39 | var bucketName = createBucket(client); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/DBConfig.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | namespace ReplicationTest 12 | { 13 | public class DBConfig(string host, int port, string dbName, string tableName, string userName, string password) 14 | { 15 | /// 호스트 이름 16 | public readonly string Host = host; 17 | 18 | /// 포트 번호 19 | public readonly int Port = port; 20 | 21 | /// 데이터베이스 이름 22 | public readonly string DBName = dbName; 23 | 24 | /// 테이블 이름 25 | public readonly string TableName = tableName; 26 | 27 | /// 사용자 이름 28 | public readonly string UserName = userName; 29 | 30 | /// 비밀번호 31 | public readonly string Password = password; 32 | 33 | public string ConnectionString 34 | => string.Format("Server={0};Port={1};Database={2};Uid={3};Pwd={4}", Host, Port, DBName, UserName, Password); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/MultipartUploadData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | import java.util.List; 14 | import java.util.ArrayList; 15 | 16 | import com.amazonaws.services.s3.model.PartETag; 17 | 18 | public class MultipartUploadData { 19 | public String uploadId; 20 | public List parts; 21 | public StringBuilder body; 22 | 23 | public MultipartUploadData() { 24 | uploadId = ""; 25 | body = new StringBuilder(); 26 | parts = new ArrayList<>(); 27 | } 28 | 29 | public int nextPartNumber() { 30 | return parts.size() + 1; 31 | } 32 | 33 | public String getBody() { 34 | return body.toString(); 35 | } 36 | 37 | public void addPart(int partNumber, String eTag) { 38 | parts.add(new PartETag(partNumber, eTag)); 39 | } 40 | 41 | public void addPart(PartETag part) { 42 | parts.add(part); 43 | } 44 | 45 | public void appendBody(String data) { 46 | body.append(data); 47 | } 48 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/ObjectVersionsData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | import com.amazonaws.services.s3.model.Tag; 19 | 20 | public class ObjectVersionsData { 21 | public String bucketName; 22 | public String key; 23 | public List tagSet; 24 | public Map versionsBody; 25 | 26 | public ObjectVersionsData() 27 | { 28 | bucketName = ""; 29 | key = ""; 30 | tagSet = new ArrayList<>(); 31 | versionsBody = new HashMap<>(); 32 | } 33 | public ObjectVersionsData(String bucketName, String key, List tagSet) 34 | { 35 | this.bucketName = bucketName; 36 | this.key = key; 37 | this.tagSet = tagSet; 38 | versionsBody = new HashMap<>(); 39 | } 40 | 41 | public void addVersion(String versionId, String body){ 42 | versionsBody.put(versionId, body); 43 | } 44 | } -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/TestCase.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | @Getter 8 | @Setter 9 | @XmlAccessorType(XmlAccessType.FIELD) 10 | public class TestCase { 11 | @XmlAttribute 12 | private String name; 13 | 14 | @XmlAttribute 15 | private String classname; 16 | 17 | @XmlAttribute 18 | private double time; 19 | 20 | @XmlElement(name = "failure") 21 | private TestResult failure; 22 | 23 | @XmlElement(name = "error") 24 | private TestResult error; 25 | 26 | @XmlElement(name = "system-out") 27 | private String systemOut; 28 | 29 | @XmlElement(name = "system-err") 30 | private String systemErr; 31 | 32 | // DB 저장을 위한 메서드들 33 | public String getResult() { 34 | if (error != null) return "error"; 35 | if (failure != null) return "failure"; 36 | return "pass"; 37 | } 38 | 39 | public String getErrorType() { 40 | TestResult result = error != null ? error : failure; 41 | return result != null ? result.getType() : null; 42 | } 43 | 44 | public String getErrorMessage() { 45 | TestResult result = error != null ? error : failure; 46 | return result != null ? result.getMessage() : null; 47 | } 48 | 49 | public String getErrorContent() { 50 | TestResult result = error != null ? error : failure; 51 | return result != null ? result.getContent() : null; 52 | } 53 | 54 | public float getTimeAsFloat() { 55 | return (float) time; 56 | } 57 | } -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Accelerate.java: -------------------------------------------------------------------------------- 1 | // package org.example.s3tests; 2 | 3 | // import org.junit.jupiter.api.Test; 4 | // import org.junit.jupiter.api.TestInfo; 5 | // import org.junit.jupiter.api.AfterEach; 6 | // import org.junit.jupiter.api.Tag; 7 | 8 | // class Accelerate { 9 | // org.example.test.Accelerate test = new org.example.test.Accelerate(); 10 | // org.example.testV2.Accelerate testV2 = new org.example.testV2.Accelerate(); 11 | 12 | // @AfterEach 13 | // void clear(TestInfo testInfo) { 14 | // test.clear(testInfo); 15 | // testV2.clear(testInfo); 16 | // } 17 | 18 | // @Test 19 | // @Tag("Put") 20 | // // 버킷 가속 설정이 가능한지 확인 21 | // void testPutBucketAccelerate() { 22 | // test.testPutBucketAccelerate(); 23 | // testV2.testPutBucketAccelerate(); 24 | // } 25 | 26 | // @Test 27 | // @Tag("Get") 28 | // // 버킷 가속 설정이 올바르게 적용되는지 확인 29 | // void testGetBucketAccelerate() { 30 | // test.testGetBucketAccelerate(); 31 | // testV2.testGetBucketAccelerate(); 32 | // } 33 | 34 | // @Test 35 | // @Tag("Change") 36 | // // 버킷 가속 설정이 변경되는지 확인 37 | // void testChangeBucketAccelerate() { 38 | // test.testChangeBucketAccelerate(); 39 | // testV2.testChangeBucketAccelerate(); 40 | // } 41 | 42 | 43 | // @Test 44 | // @Tag("Error") 45 | // // 버킷 가속 설정을 잘못 입력했을 때 에러가 발생하는지 확인 46 | // void testPutBucketAccelerateInvalid() { 47 | // test.testPutBucketAccelerateInvalid(); 48 | // testV2.testPutBucketAccelerateInvalid(); 49 | // } 50 | // } 51 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Notification.java: -------------------------------------------------------------------------------- 1 | package org.example.s3tests; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.Tag; 6 | import org.junit.jupiter.api.TestInfo; 7 | 8 | /** 9 | * 버킷의 알람 기능을 테스트하는 클래스 10 | */ 11 | class Notification { 12 | 13 | org.example.test.Notification test = new org.example.test.Notification(); 14 | org.example.testV2.Notification testV2 = new org.example.testV2.Notification(); 15 | 16 | /** 17 | * 테스트 정리 작업 수행 18 | * @param testInfo 테스트 정보 19 | */ 20 | @AfterEach 21 | void clear(TestInfo testInfo) { 22 | test.clear(testInfo); 23 | testV2.clear(testInfo); 24 | } 25 | 26 | /** 27 | * 버킷에 알람 설정이 없는지 확인 28 | */ 29 | @Test 30 | @Tag("Get") 31 | void testNotificationGetEmpty() { 32 | test.testNotificationGetEmpty(); 33 | testV2.testNotificationGetEmpty(); 34 | } 35 | 36 | /** 37 | * 버킷에 알람 설정이 가능한지 확인 38 | */ 39 | @Test 40 | @Tag("Put") 41 | void testNotificationPut() { 42 | test.testNotificationPut(); 43 | testV2.testNotificationPut(); 44 | } 45 | 46 | /** 47 | * 버킷에 알람 설정이 되어있는지 확인 48 | */ 49 | @Test 50 | @Tag("Get") 51 | void testNotificationGet() { 52 | test.testNotificationGet(); 53 | testV2.testNotificationGet(); 54 | } 55 | 56 | /** 57 | * 버킷에 알람 설정이 삭제되는지 확인 58 | */ 59 | @Test 60 | @Tag("Delete") 61 | void testNotificationDelete() { 62 | test.testNotificationDelete(); 63 | testV2.testNotificationDelete(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # S3 compatibility test for Python 2 | 3 | - 이 테스트는 [ceph/s3-tests](https://github.com/ceph/s3-tests)를 복제하여 작성한 프로그램입니다. 4 | - 아마존에서 제공하는 S3 Api를 사용하여 S3 호환 프로그램에 대한 기능점검 프로그램입니다. 5 | - 별도의 유틸을 이용하여 보기 쉽게 결과물을 출력하는 기능을 포함하고 있습니다. 6 | 7 | ## 원본에서 변경점 8 | 9 | * 함수에서 클래스로 변경 10 | * AWS S3에서 지원하지 않는 기능 테스트 삭제 및 주석처리 11 | 12 | ## 구동환경 13 | 14 | * python : 3.4.3 15 | * OS : Centos 7.5 16 | * python-virtualenv 17 | 18 | ## 테스트 환경 구성 19 | 20 | ### Centos7에 virtualenv 설치 21 | 22 | ``` bash 23 | # pip 설치 24 | sudo yum install epel-release 25 | yum -y update 26 | yum -y install python-pip 27 | # virtualenv 설치 28 | sudo pip install virtualenv 29 | # python module 설치 30 | ./bootstrap 31 | # virtualenv 환경 설정 32 | mkdir virtualenv 33 | virtualenv virtualenv 34 | source ./virtualenv/bin/activate 35 | ``` 36 | 37 | ## 테스트 38 | 39 | ``` bash 40 | S3TEST_CONF=sample.conf \ 41 | ./virtualenv/bin/nosetests \ 42 | -v --with-xunit --xunit-file=../xunit-to-html-master/Result_file.xml \ 43 | --nologcapture -a '!fails_on_aws' --with-id --id-file=mylist \ 44 | --failure-detail s3tests_boto3.functional.test_s3 || true 45 | ``` 46 | 47 | ## 테스트 결과 레포트 48 | 49 | ``` bash 50 | cd ..xunit-to-html-master 51 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 52 | ``` 53 | 54 | 테스트 결과 레포트는 [링크](https://github.com/Zir0-93/xunit-to-html)를 사용하여 작성했습니다. 55 | 56 | 테스트 결과는 **./xunit-to-html-master/Result_java.html**로 확인 가능합니다. 57 | 58 | ![kjw_s3tests_0001](xunit-to-html-master/kjw_s3tests_0001.PNG "kjw_s3tests_0001.PNG") -------------------------------------------------------------------------------- /dotnet/Data/S3Config.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Text.Json; 12 | using Amazon; 13 | 14 | namespace s3tests 15 | { 16 | public class S3Config 17 | { 18 | public string Address; 19 | public int Port; 20 | public int SSLPort; 21 | public string RegionName; 22 | 23 | public S3Config() 24 | { 25 | Init(); 26 | } 27 | public S3Config(string Address, int Port, int SSLPort, string RegionName) 28 | { 29 | this.Address = Address; 30 | this.Port = Port; 31 | this.SSLPort = SSLPort; 32 | this.RegionName = RegionName; 33 | } 34 | 35 | public void Init() 36 | { 37 | Address = ""; 38 | Port = 0; 39 | SSLPort = 0; 40 | RegionName = ""; 41 | } 42 | 43 | public override string ToString() => $"S3Config {JsonSerializer.Serialize(this)}"; 44 | 45 | public bool IsAWS { get => string.IsNullOrEmpty(Address); } 46 | 47 | public string GetURL(bool isSecure) => isSecure ? $"{MainData.HTTPS}{Address}:{SSLPort}" : $"{MainData.HTTP}{Address}:{Port}"; 48 | 49 | public RegionEndpoint GetRegion() => RegionEndpoint.GetBySystemName(RegionName); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Utility/S3ChecksumAlgorithm.java: -------------------------------------------------------------------------------- 1 | package org.example.Utility; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import software.amazon.awssdk.checksums.spi.ChecksumAlgorithm; 7 | 8 | public class S3ChecksumAlgorithm implements ChecksumAlgorithm { 9 | public static final String CRC32 = "CRC32"; 10 | public static final String CRC32C = "CRC32C"; 11 | public static final String SHA1 = "SHA1"; 12 | public static final String SHA256 = "SHA256"; 13 | public static final String MD5 = "MD5"; 14 | public static final String CRC64NVME = "CRC64NVME"; 15 | 16 | private List algorithms = Arrays.asList(CRC32, CRC32C, SHA1, SHA256, MD5, CRC64NVME); 17 | 18 | String algorithm; 19 | 20 | // 알고리즘 입력 21 | public void fromAlgorithm(String algorithm) { 22 | if (!algorithms.contains(algorithm)) { 23 | throw new IllegalArgumentException("Invalid algorithm: " + algorithm); 24 | } 25 | this.algorithm = algorithm; 26 | } 27 | 28 | public static ChecksumAlgorithm withAlgorithm( 29 | software.amazon.awssdk.services.s3.model.ChecksumAlgorithm algorithm) { 30 | var s3Algorithm = new S3ChecksumAlgorithm(); 31 | switch (algorithm) { 32 | case CRC32 -> s3Algorithm.fromAlgorithm(CRC32); 33 | case CRC32_C -> s3Algorithm.fromAlgorithm(CRC32C); 34 | case CRC64_NVME -> s3Algorithm.fromAlgorithm(CRC64NVME); 35 | case SHA1 -> s3Algorithm.fromAlgorithm(SHA1); 36 | case SHA256 -> s3Algorithm.fromAlgorithm(SHA256); 37 | default -> throw new IllegalArgumentException("Invalid algorithm: " + algorithm); 38 | } 39 | return s3Algorithm; 40 | } 41 | 42 | @Override 43 | public String algorithmId() { 44 | // AWS SDK에서 사용하는 알고리즘 ID 문자열 반환 45 | return algorithm; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | # S3 compatibility test for Java 2 | 3 | 이 테스트는 아마존에서 제공하는 S3 Api를 사용하여 S3 호환 프로그램에 대한 기능점검 프로그램입니다. 4 | 5 | 별도의 유틸을 이용하여 보기 쉽게 결과물을 출력하는 기능을 포함하고 있습니다. 6 | 7 | ## 구동환경 8 | 9 | * Java : 17 이상 10 | * maven : 3.9.5 이상 11 | 12 | ## How to Build 13 | 14 | - 빌드하기 위해서 테스트 과정을 생략하는 옵션을 추가해야 합니다. 15 | 16 | ``` shell 17 | mvn clean package -DskipTests 18 | ``` 19 | 20 | ## 테스트 방법 21 | 22 | ### mvn으로 테스트할 경우 23 | #### Window 24 | 25 | ``` bat 26 | @REM 설정파일 경로 27 | SET S3TESTS_INI=sample.ini 28 | call mvn clean 29 | call mvn test surefire-report:report 30 | .\junit-merger.exe target/results > xunit-to-html-master\Result_java.xml 31 | cd xunit-to-html-master 32 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 33 | start Result_java.html 34 | ``` 35 | 36 | #### Linux 37 | 38 | ``` bash 39 | #설정파일 경로 40 | export S3TESTS_INI=sample.ini 41 | mvn clean 42 | mvn test surefire-report:report 43 | python ./merge_junit_results.py ./target/results/*.xml > ../xunit-to-html-master/Result_java.xml 44 | cd ../xunit-to-html-master 45 | java -jar saxon9he.jar -o:Result_java.html -s:Result_java.xml -xsl:xunit_to_html.xsl 46 | ``` 47 | 48 | ### 빌드한 경우 49 | 50 | - 빌드한 프로그램으로 테스트 할 경우 레포트는 생성할 수 없습니다. 51 | - 테스트 결과가 콘솔창에 출력됩니다. 52 | 53 | #### Windows 54 | ``` shell 55 | SET S3TESTS_INI=sample.ini 56 | java -jar s3tests-java 57 | ``` 58 | 59 | #### Linux 60 | ``` shell 61 | export S3TESTS_INI=sample.ini 62 | ./s3tests-java 63 | ``` 64 | 65 | ## 테스트 결과 레포트 66 | 67 | - 테스트 결과 레포트는 [링크](https://github.com/Zir0-93/xunit-to-html)를 사용하여 작성했습니다. 68 | - 테스트 결과는 **../xunit-to-html-master/Result_java.html**로 확인 가능합니다. 69 | - 테스트 결과 예제 : [kjw_s3tests_0001](xunit-to-html-master/kjw_s3tests_0001.PNG "kjw_s3tests_0001.PNG") 70 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/ReplicationTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | 1.1.0.0 7 | 8 | 9 | 10 | bin\ 11 | 12 | 13 | 14 | bin\ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | PreserveNewest 43 | 44 | 45 | PreserveNewest 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /python/sample.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | ## this section is just used for host, port and bucket_prefix 3 | 4 | # host set for rgw in vstart.sh 5 | host = 127.0.0.1 6 | 7 | # port set for rgw in vstart.sh 8 | port = 8080 9 | 10 | ## say "False" to disable TLS 11 | is_secure = False 12 | 13 | [fixtures] 14 | ## all the buckets created will start with this prefix; 15 | ## {random} will be filled with random characters to pad 16 | ## the prefix to 30 characters long, and avoid collisions 17 | bucket prefix = s3-test-python-{random}- 18 | 19 | [s3 main] 20 | # main display_name set in vstart.sh 21 | display_name = test1 22 | 23 | # main user_idname set in vstart.sh 24 | user_id = 1 25 | 26 | # main email set in vstart.sh 27 | email = test2@test.co.kr 28 | 29 | # zonegroup api_name for bucket location 30 | api_name = test 31 | 32 | ## main AWS access key 33 | access_key = 123123123 34 | 35 | ## main AWS secret key 36 | secret_key = 123123123 37 | 38 | ## replace with key id obtained when secret is created, or delete if KMS not tested 39 | #kms_keyid = 01234567-89ab-cdef-0123-456789abcdef 40 | 41 | [s3 alt] 42 | # alt display_name set in vstart.sh 43 | display_name = test2 44 | ## alt email set in vstart.sh 45 | email = test2@test.co.kr 46 | 47 | # alt user_id set in vstart.sh 48 | user_id = 2 49 | 50 | # alt AWS access key set in vstart.sh 51 | access_key = 123123123 52 | 53 | # alt AWS secret key set in vstart.sh 54 | secret_key = 1231231234 55 | 56 | [s3 tenant] 57 | # tenant display_name set in vstart.sh 58 | display_name = test3 59 | 60 | # tenant user_id set in vstart.sh 61 | user_id = 3 62 | 63 | # tenant AWS secret key set in vstart.sh 64 | access_key = 123123123 65 | 66 | # tenant AWS secret key set in vstart.sh 67 | secret_key = 1231231234 68 | 69 | # tenant email set in vstart.sh 70 | email = gcpark_tenant@test.co.kr 71 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Website.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.Test; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.AfterEach; 16 | import org.junit.jupiter.api.Tag; 17 | 18 | /** 19 | * 버킷의 웹사이트 기능을 테스트하는 클래스 20 | */ 21 | class Website { 22 | org.example.test.Website test = new org.example.test.Website(); 23 | org.example.testV2.Website testV2 = new org.example.testV2.Website(); 24 | 25 | /** 26 | * 테스트 정리 작업 수행 27 | * @param testInfo 테스트 정보 28 | */ 29 | @AfterEach 30 | void clear(TestInfo testInfo) { 31 | test.clear(testInfo); 32 | testV2.clear(testInfo); 33 | } 34 | 35 | /** 36 | * 버킷의 Website 설정 조회 확인 37 | */ 38 | @Test 39 | @Tag("Check") 40 | void testWebsiteGetBuckets() { 41 | test.testWebsiteGetBuckets(); 42 | testV2.testWebsiteGetBuckets(); 43 | } 44 | 45 | /** 46 | * 버킷의 Website 설정이 가능한지 확인 47 | */ 48 | @Test 49 | @Tag("Check") 50 | void testWebsitePutBuckets() { 51 | test.testWebsitePutBuckets(); 52 | testV2.testWebsitePutBuckets(); 53 | } 54 | 55 | /** 56 | * 버킷의 Website 설정이 삭제가능한지 확인 57 | */ 58 | @Test 59 | @Tag("Delete") 60 | void testWebsiteDeleteBuckets() { 61 | test.testWebsiteDeleteBuckets(); 62 | testV2.testWebsiteDeleteBuckets(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/DeleteBucket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | /** 19 | * 버킷 삭제 기능 테스트 20 | */ 21 | class DeleteBucket { 22 | 23 | org.example.test.DeleteBucket test = new org.example.test.DeleteBucket(); 24 | org.example.testV2.DeleteBucket testV2 = new org.example.testV2.DeleteBucket(); 25 | 26 | /** 27 | * 테스트 정리 작업 수행 28 | */ 29 | @AfterEach 30 | void clear(TestInfo testInfo) { 31 | test.clear(testInfo); 32 | testV2.clear(testInfo); 33 | } 34 | 35 | /** 36 | * 존재하지 않는 버킷을 삭제하려 했을 경우 실패 확인 37 | */ 38 | @Test 39 | @Tag("ERROR") 40 | void testBucketDeleteNotExist() { 41 | test.testBucketDeleteNotExist(); 42 | testV2.testBucketDeleteNotExist(); 43 | } 44 | 45 | /** 46 | * 내용이 비어있지 않은 버킷을 삭제하려 했을 경우 실패 확인 47 | */ 48 | @Test 49 | @Tag("ERROR") 50 | void testBucketDeleteNonempty() { 51 | test.testBucketDeleteNonempty(); 52 | testV2.testBucketDeleteNonempty(); 53 | } 54 | 55 | /** 56 | * 이미 삭제된 버킷을 다시 삭제 시도할 경우 실패 확인 57 | */ 58 | @Test 59 | @Tag("ERROR") 60 | void testBucketCreateDelete() { 61 | test.testBucketCreateDelete(); 62 | testV2.testBucketCreateDelete(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/README.md: -------------------------------------------------------------------------------- 1 | # S3 Replication test for .Net Framework 2 | 3 | 이 테스트는 아마존에서 제공하는 S3 Api를 사용하여 S3 Replication 기능에 대한 점검 프로그램입니다. 4 | 5 | ## 테스트 항목 6 | 7 | - 복제 기능의 정상 동작 확인(Filtering, DeleteMarker, versionId) 8 | - 로컬 시스템과 외부 시스템간의 복제 가능 여부 9 | - SSE-S3 설정된 버킷과 일반 버킷간의 복제 가능 여부 10 | - Http, Https 환경에서 정상적인 동작 확인 11 | 12 | ## 테스트 순서 13 | 14 | 1. 버킷 생성(source, target) 15 | 2. 버킷에 복제설정 16 | 3. 다양한 오브젝트 업로드 17 | 4. 설정한 시간만큼 대기 18 | 5. 원본 버킷과 대상 버킷을 ListVersions 하여 비교 19 | 20 | ## 구동환경 21 | 22 | * .Net Core : 3.1 이상 23 | * OS : Window 10 이상 24 | 25 | ## How to Build 26 | 27 | ### dotnet 설치 28 | 29 | #### Window 10 30 | - 설치파일 링크 : [Link](https://dotnet.microsoft.com/en-us/download/dotnet/3.1) 31 | 32 | #### CentOS 7 33 | ``` 34 | sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm 35 | sudo yum install -y dotnet-sdk-3.1 36 | ``` 37 | 38 | ### Build 39 | ``` shell 40 | dotnet build -c Release 41 | ``` 42 | 43 | ## 테스트 방법 44 | 45 | ### Config 설정 46 | ``` ini 47 | [Global] 48 | # replication이 완료될때까지 대기하는 시간 (단위 : sec) 49 | Delay = 30 50 | # 버전 정보 동기화 체크 여부 51 | CheckVersionId = true 52 | # 기본 설정 버킷 명 53 | MainNormalBucket = bucket-normal-bucket 54 | # SSE-S3 설정 버킷 명 55 | MainEncryptionBucket = bucket-encryption-bucket 56 | # 테스트용 생성 버킷 접두어 57 | TargetBucketPrefix = test- 58 | #Test Option 59 | # 0 = ALL 60 | # 1 = Local Only 61 | # 2 = Another Only 62 | TestOption = 0 63 | # SSL Option 64 | # 0 = ALL 65 | # 1 = Http Only 66 | # 2 = Https Only 67 | SSL = 0 68 | 69 | # 원본 유저 및 시스템 70 | [Main User] 71 | URL = 0.0.0.0 72 | Port = 80 73 | SSLPort = 443 74 | AccessKey = accesskey 75 | SecretKey = secretkey 76 | 77 | # 대상 유저 및 시스템 78 | [Alt User] 79 | URL = 0.0.0.0 80 | Port = 80 81 | SSLPort = 443 82 | AccessKey = accesskey 83 | SecretKey = secretkey 84 | 85 | ``` 86 | 87 | ### 테스트 실행 88 | ``` ps1 89 | dotnet ReplicationTest.dll 90 | ``` 91 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using log4net; 12 | using log4net.Config; 13 | using System.Reflection; 14 | 15 | [assembly: XmlConfigurator(ConfigFile = "LogConfig.xml")] 16 | 17 | namespace ReplicationTest 18 | { 19 | static class Program 20 | { 21 | private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 22 | static void Main(string[] args) 23 | { 24 | DBManager db = null; 25 | int buildId = 0; 26 | string configPath = null; 27 | 28 | // Config 설정 29 | if (args.Length > 1) 30 | { 31 | configPath = args[1]; 32 | if (string.IsNullOrEmpty(configPath)) 33 | { 34 | log.Error("config path is empty!"); 35 | return; 36 | } 37 | } 38 | 39 | MainConfig config = new(configPath); 40 | config.GetConfig(); 41 | log.Info("Get Config!"); 42 | 43 | // DB 설정 44 | if (args.Length > 0) 45 | { 46 | if (!int.TryParse(args[0], out buildId)) 47 | { 48 | log.Error("is Not Build id"); 49 | return; 50 | } 51 | if (buildId > 0) 52 | { 53 | //DB 연결 54 | db = new DBManager(config.DB, buildId); 55 | if (!db.Connect()) 56 | { 57 | log.Error("DB is not connected"); 58 | return; 59 | } 60 | log.Info("DB is connected!"); 61 | } 62 | } 63 | 64 | var test = new ReplicationTest(config, db); 65 | test.Test(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/Localtest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import java.util.List; 14 | import java.util.Random; 15 | 16 | import org.example.Utility.Utils; 17 | import org.junit.jupiter.api.Tag; 18 | import org.junit.jupiter.api.Test; 19 | 20 | public class Localtest extends TestBase { 21 | private static final Random random = new Random(); 22 | 23 | @org.junit.jupiter.api.BeforeAll 24 | public static void beforeAll() { 25 | System.out.println("Localtest Start"); 26 | } 27 | 28 | @org.junit.jupiter.api.AfterAll 29 | public static void afterAll() { 30 | System.out.println("Localtest End"); 31 | } 32 | 33 | @Test 34 | @Tag("Get") 35 | public void testBucketInfo() { 36 | // var client = getClient(); 37 | // var bucketName = createBucket(client); 38 | // var keys = List.of("test1", "test2", "test3", "test4", "test5"); 39 | // var totalSize = 0; 40 | 41 | // // 다양한 오브젝트 업로드 42 | // for (var key : keys) { 43 | // var size = random.nextInt(1024 * 1024 * 1); 44 | // var body = Utils.randomTextToLong(size); 45 | // client.putObject(bucketName, key, body); 46 | // totalSize += size; 47 | // } 48 | 49 | // // 버킷 정보 조회 50 | // var portal = new Portal(client); 51 | // var bucketInfo = portal.getBucketInfo(bucketName); 52 | // assertEquals(keys.size(), bucketInfo.fileCount); 53 | // assertEquals(totalSize, bucketInfo.totalSize); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dotnet/s3tests.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.30204.135 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "s3tests", "s3tests.csproj", "{A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}" 6 | EndProject 7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EB8AB644-73B2-412F-8446-16088FAA1EC2}" 8 | ProjectSection(SolutionItems) = preProject 9 | .editorconfig = .editorconfig 10 | EndProjectSection 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Release|Any CPU = Release|Any CPU 17 | Release|x64 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Debug|x64.ActiveCfg = Debug|x64 23 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Debug|x64.Build.0 = Debug|x64 24 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Release|x64.ActiveCfg = Release|x64 27 | {A4E85847-DF4E-4B9D-8A04-61DD7A307A6D}.Release|x64.Build.0 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(ExtensibilityGlobals) = postSolution 33 | SolutionGuid = {273EE8C9-A022-4112-AA4F-C08F2214D862} 34 | EndGlobalSection 35 | GlobalSection(SubversionScc) = preSolution 36 | Svn-Managed = True 37 | Manager = AnkhSVN2019 - Subversion Support for Visual Studio 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /python/s3tests_boto3/functional/policy.py: -------------------------------------------------------------------------------- 1 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 2 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 3 | #the GNU General Public License as published by the Free Software Foundation, either version 4 | #3 of the License. See LICENSE for details 5 | 6 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 7 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 8 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 9 | import json 10 | 11 | class Statement(object): 12 | def __init__(self, action, resource, principal = {"AWS" : "*"}, effect= "Allow", condition = None): 13 | self.principal = principal 14 | self.action = action 15 | self.resource = resource 16 | self.condition = condition 17 | self.effect = effect 18 | 19 | def to_dict(self): 20 | d = { "Action" : self.action, 21 | "Principal" : self.principal, 22 | "Effect" : self.effect, 23 | "Resource" : self.resource 24 | } 25 | 26 | if self.condition is not None: 27 | d["Condition"] = self.condition 28 | 29 | return d 30 | 31 | class Policy(object): 32 | def __init__(self): 33 | self.statements = [] 34 | 35 | def add_statement(self, s): 36 | self.statements.append(s) 37 | return self 38 | 39 | def to_json(self): 40 | policy_dict = { 41 | "Version" : "2012-10-17", 42 | "Statement": 43 | [s.to_dict() for s in self.statements] 44 | } 45 | 46 | return json.dumps(policy_dict) 47 | 48 | def make_json_policy(action, resource, principal={"AWS": "*"}, conditions=None): 49 | """ 50 | Helper function to make single statement policies 51 | """ 52 | s = Statement(action, resource, principal, condition=conditions) 53 | p = Policy() 54 | return p.add_statement(s).to_json() 55 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Cors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | /** 19 | * CORS 테스트 20 | */ 21 | class Cors { 22 | org.example.test.Cors test = new org.example.test.Cors(); 23 | org.example.testV2.Cors testV2 = new org.example.testV2.Cors(); 24 | 25 | /** 26 | * 테스트 정리 작업 수행 27 | */ 28 | @AfterEach 29 | void clear(TestInfo testInfo) { 30 | test.clear(testInfo); 31 | testV2.clear(testInfo); 32 | } 33 | 34 | /** 35 | * 버킷의 cors정보 세팅 성공 확인 36 | */ 37 | @Test 38 | @Tag("Check") 39 | void testSetCors() { 40 | test.testSetCors(); 41 | testV2.testSetCors(); 42 | } 43 | 44 | /** 45 | * 버킷의 cors정보를 URL로 읽고 쓰기 성공/실패 확인 46 | */ 47 | @Test 48 | @Tag("Post") 49 | void testCorsOriginResponse() { 50 | test.testCorsOriginResponse(); 51 | testV2.testCorsOriginResponse(); 52 | } 53 | 54 | /** 55 | * 와일드카드 문자만 입력하여 cors설정을 하였을때 정상적으로 동작하는지 확인 56 | */ 57 | @Test 58 | @Tag("Post") 59 | void testCorsOriginWildcard() { 60 | test.testCorsOriginWildcard(); 61 | testV2.testCorsOriginWildcard(); 62 | } 63 | 64 | /** 65 | * cors옵션에서 사용자 추가 헤더를 설정하고 존재하지 않는 헤더를 request 설정한 채로 cors호출하면 실패하는지 확인 66 | */ 67 | @Test 68 | @Tag("Post") 69 | void testCorsHeaderOption() { 70 | test.testCorsHeaderOption(); 71 | testV2.testCorsHeaderOption(); 72 | } 73 | } -------------------------------------------------------------------------------- /python/README.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | S3 compatibility tests 3 | ======================== 4 | 5 | This is a set of unofficial Amazon AWS S3 compatibility 6 | tests, that can be useful to people implementing software 7 | that exposes an S3-like API. The tests use the Boto2 and Boto3 libraries. 8 | 9 | The tests use the Nose test framework. To get started, ensure you have 10 | the ``virtualenv`` software installed; e.g. on Debian/Ubuntu:: 11 | 12 | sudo apt-get install python-virtualenv 13 | 14 | and then run:: 15 | 16 | ./bootstrap 17 | 18 | You will need to create a configuration file with the location of the 19 | service and two different credentials. A sample configuration file named 20 | ``s3tests.conf.SAMPLE`` has been provided in this repo. This file can be 21 | used to run the s3 tests on a Ceph cluster started with vstart. 22 | 23 | Once you have that file copied and edited, you can run the tests with:: 24 | 25 | S3TEST_CONF=your.conf ./virtualenv/bin/nosetests 26 | 27 | You can specify which directory of tests to run:: 28 | 29 | S3TEST_CONF=your.conf ./virtualenv/bin/nosetests s3tests.functional 30 | 31 | You can specify which file of tests to run:: 32 | 33 | S3TEST_CONF=your.conf ./virtualenv/bin/nosetests s3tests.functional.test_s3 34 | 35 | You can specify which test to run:: 36 | 37 | S3TEST_CONF=your.conf ./virtualenv/bin/nosetests s3tests.functional.test_s3:test_bucket_list_empty 38 | 39 | To gather a list of tests being run, use the flags:: 40 | 41 | -v --collect-only 42 | 43 | Some tests have attributes set based on their current reliability and 44 | things like AWS not enforcing their spec stricly. You can filter tests 45 | based on their attributes:: 46 | 47 | S3TEST_CONF=aws.conf ./virtualenv/bin/nosetests -a '!fails_on_aws' 48 | 49 | Most of the tests have both Boto3 and Boto2 versions. Tests written in 50 | Boto2 are in the ``s3tests`` directory. Tests written in Boto3 are 51 | located in the ``s3test_boto3`` directory. 52 | 53 | You can run only the boto3 tests with:: 54 | 55 | S3TEST_CONF=your.conf ./virtualenv/bin/nosetests -v -s -A 'not fails_on_rgw' s3tests_boto3.functional 56 | 57 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/testV2/Payment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.testV2; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import software.amazon.awssdk.services.s3.model.Payer; 19 | 20 | public class Payment extends TestBase { 21 | @org.junit.jupiter.api.BeforeAll 22 | public static void beforeAll() { 23 | System.out.println("Payment V2 Start"); 24 | } 25 | 26 | @org.junit.jupiter.api.AfterAll 27 | public static void afterAll() { 28 | System.out.println("Payment V2 End"); 29 | } 30 | 31 | @Test 32 | @Tag("Put") 33 | public void testPutBucketRequestPayment() { 34 | var client = getClient(); 35 | var bucketName = createBucket(client); 36 | 37 | client.putBucketRequestPayment( 38 | p -> p.bucket(bucketName).requestPaymentConfiguration(r -> r.payer(Payer.REQUESTER))); 39 | } 40 | 41 | @Test 42 | @Tag("Get") 43 | public void testGetBucketRequestPayment() { 44 | var client = getClient(); 45 | var bucketName = createBucket(client); 46 | 47 | var result = client.getBucketRequestPayment(p -> p.bucket(bucketName)); 48 | assertEquals(Payer.BUCKET_OWNER, result.payer()); 49 | } 50 | 51 | @Test 52 | @Tag("Get") 53 | public void testSetGetBucketRequestPayment() { 54 | var client = getClient(); 55 | var bucketName = createBucket(client); 56 | 57 | client.putBucketRequestPayment(p -> p.bucket(bucketName).requestPaymentConfiguration(r -> r.payer(Payer.REQUESTER))); 58 | var result = client.getBucketRequestPayment(p -> p.bucket(bucketName)); 59 | assertEquals(Payer.REQUESTER, result.payer()); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /python/s3tests_boto3/functional/utils.py: -------------------------------------------------------------------------------- 1 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 2 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 3 | #the GNU General Public License as published by the Free Software Foundation, either version 4 | #3 of the License. See LICENSE for details 5 | 6 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 7 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 8 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 9 | import random 10 | import requests 11 | import string 12 | import time 13 | 14 | from nose.tools import eq_ as eq 15 | 16 | def assert_raises(excClass, callableObj, *args, **kwargs): 17 | """ 18 | Like unittest.TestCase.assertRaises, but returns the exception. 19 | """ 20 | try: 21 | callableObj(*args, **kwargs) 22 | except excClass as e: 23 | return e 24 | else: 25 | if hasattr(excClass, '__name__'): 26 | excName = excClass.__name__ 27 | else: 28 | excName = str(excClass) 29 | raise AssertionError("%s not raised" % excName) 30 | 31 | def generate_random(size, part_size=5*1024*1024): 32 | """ 33 | Generate the specified number random data. 34 | (actually each MB is a repetition of the first KB) 35 | """ 36 | chunk = 1024 37 | allowed = string.ascii_letters 38 | for x in range(0, size, part_size): 39 | strpart = ''.join([allowed[random.randint(0, len(allowed) - 1)] for _ in range(chunk)]) 40 | s = '' 41 | left = size - x 42 | this_part_size = min(left, part_size) 43 | for y in range(this_part_size // chunk): 44 | s = s + strpart 45 | s = s + strpart[:(this_part_size % chunk)] 46 | yield s 47 | if (x == size): 48 | return 49 | 50 | def _get_status(response): 51 | status = response['ResponseMetadata']['HTTPStatusCode'] 52 | return status 53 | 54 | def _get_status_and_error_code(response): 55 | status = response['ResponseMetadata']['HTTPStatusCode'] 56 | error_code = response['Error']['Code'] 57 | return status, error_code 58 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/Payment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import com.amazonaws.services.s3.model.RequestPaymentConfiguration; 19 | import com.amazonaws.services.s3.model.SetRequestPaymentConfigurationRequest; 20 | import com.amazonaws.services.s3.model.RequestPaymentConfiguration.Payer; 21 | 22 | public class Payment extends TestBase { 23 | @org.junit.jupiter.api.BeforeAll 24 | public static void beforeAll() { 25 | System.out.println("Payment Start"); 26 | } 27 | 28 | @org.junit.jupiter.api.AfterAll 29 | public static void afterAll() { 30 | System.out.println("Payment End"); 31 | } 32 | 33 | @Test 34 | @Tag("Put") 35 | public void testPutBucketRequestPayment() { 36 | var client = getClient(); 37 | var bucketName = createBucket(client); 38 | 39 | client.setRequestPaymentConfiguration(new SetRequestPaymentConfigurationRequest(bucketName, 40 | new RequestPaymentConfiguration(Payer.Requester))); 41 | } 42 | 43 | @Test 44 | @Tag("Get") 45 | public void testGetBucketRequestPayment() { 46 | var client = getClient(); 47 | var bucketName = createBucket(client); 48 | 49 | var result = client.isRequesterPaysEnabled(bucketName); 50 | assertEquals(false, result); 51 | } 52 | 53 | @Test 54 | @Tag("Get") 55 | public void testSetGetBucketRequestPayment() { 56 | var client = getClient(); 57 | var bucketName = createBucket(client); 58 | 59 | client.setRequestPaymentConfiguration(new SetRequestPaymentConfigurationRequest(bucketName, 60 | new RequestPaymentConfiguration(Payer.Requester))); 61 | var result = client.isRequesterPaysEnabled(bucketName); 62 | assertEquals(true, result); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Ownership.java: -------------------------------------------------------------------------------- 1 | package org.example.s3tests; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.Tag; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.TestInfo; 7 | 8 | /** 9 | * 버킷과 오브젝트의 소유권 기능을 테스트하는 클래스 10 | */ 11 | class Ownership { 12 | 13 | org.example.test.Ownership test = new org.example.test.Ownership(); 14 | org.example.testV2.Ownership testV2 = new org.example.testV2.Ownership(); 15 | 16 | /** 17 | * 테스트 정리 작업 수행 18 | * @param testInfo 테스트 정보 19 | */ 20 | @AfterEach 21 | void clear(TestInfo testInfo) { 22 | test.clear(testInfo); 23 | testV2.clear(testInfo); 24 | } 25 | 26 | /** 27 | * 버킷의 소유권 조회 확인 28 | */ 29 | @Test 30 | @Tag("Get") 31 | void testGetBucketOwnership() { 32 | test.testGetBucketOwnership(); 33 | testV2.testGetBucketOwnership(); 34 | } 35 | 36 | /** 37 | * 버킷을 생성할때 소유권 설정 확인 38 | */ 39 | @Test 40 | @Tag("Put") 41 | void testCreateBucketWithOwnership() { 42 | test.testCreateBucketWithOwnership(); 43 | testV2.testCreateBucketWithOwnership(); 44 | } 45 | 46 | /** 47 | * 버킷의 소유권 변경 확인 48 | */ 49 | @Test 50 | @Tag("Put") 51 | void testChangeBucketOwnership() { 52 | test.testChangeBucketOwnership(); 53 | testV2.testChangeBucketOwnership(); 54 | } 55 | 56 | /** 57 | * [BucketOwnerEnforced] 버킷 ACL 설정이 실패하는지 확인 58 | */ 59 | @Test 60 | @Tag("Error") 61 | void testBucketOwnershipDenyACL() { 62 | test.testBucketOwnershipDenyACL(); 63 | testV2.testBucketOwnershipDenyACL(); 64 | } 65 | 66 | /** 67 | * [BucketOwnerEnforced] 오브젝트 ACL 설정이 실패하는지 확인 68 | */ 69 | @Test 70 | @Tag("Error") 71 | void testBucketOwnershipDenyObjectACL() { 72 | test.testBucketOwnershipDenyObjectACL(); 73 | testV2.testBucketOwnershipDenyObjectACL(); 74 | } 75 | 76 | /** 77 | * ACL 설정된 오브젝트에 소유권을 BucketOwnerEnforced로 변경해도 접근 가능한지 확인 78 | */ 79 | @Test 80 | @Tag("Check") 81 | void testObjectOwnershipDenyChange() { 82 | test.testObjectOwnershipDenyChange(); 83 | testV2.testObjectOwnershipDenyChange(); 84 | } 85 | 86 | /** 87 | * ACL 설정된 오브젝트에 소유권을 BucketOwnerEnforced로 변경할경우 ACL 설정이 실패하는지 확인 88 | */ 89 | @Test 90 | @Tag("Error") 91 | void testObjectOwnershipDenyACL() { 92 | test.testObjectOwnershipDenyACL(); 93 | testV2.testObjectOwnershipDenyACL(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/TestSuite.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import java.io.File; 7 | import java.util.List; 8 | 9 | @Getter 10 | @Setter 11 | @XmlRootElement(name = "testsuite") 12 | @XmlAccessorType(XmlAccessType.FIELD) 13 | public class TestSuite { 14 | @XmlAttribute 15 | private int tests; 16 | 17 | @XmlAttribute 18 | private int errors; 19 | 20 | @XmlAttribute 21 | private int skipped; 22 | 23 | @XmlAttribute 24 | private int failures; 25 | 26 | @XmlAttribute 27 | private double time; 28 | 29 | @XmlElement(name = "testcase") 30 | private List testCases; 31 | 32 | @XmlElement(name = "properties") 33 | private Properties properties; 34 | 35 | private String resultFileName; 36 | 37 | // Additional business logic methods 38 | public int getPassed() { 39 | return tests - failures - errors - skipped; 40 | } 41 | 42 | public float getTimeAsFloat() { 43 | return (float) time; 44 | } 45 | 46 | public void setSourceFile(String filePath) { 47 | this.resultFileName = parseFileName(filePath); 48 | } 49 | 50 | private String parseFileName(String filePath) { 51 | int index = filePath.lastIndexOf(File.separator) + 1; 52 | return filePath.substring(index).replace(".xml", ""); 53 | } 54 | 55 | public String getLanguage() { 56 | if (properties != null && properties.getProperties() != null) { 57 | for (Property prop : properties.getProperties()) { 58 | if ("java.specification.version".equals(prop.getName())) { 59 | return "Java"; 60 | } 61 | // 다른 언어 타입도 추가 가능 62 | } 63 | } 64 | return "Unknown"; 65 | } 66 | 67 | public String getSdkVersion() { 68 | if (properties != null && properties.getProperties() != null) { 69 | for (Property prop : properties.getProperties()) { 70 | if ("java.class.path".equals(prop.getName())) { 71 | String classPath = prop.getValue(); 72 | // AWS SDK v2 버전 찾기 73 | int sdkIndex = classPath.indexOf("/software/amazon/awssdk/s3/"); 74 | if (sdkIndex != -1) { 75 | int startIndex = sdkIndex + "/software/amazon/awssdk/s3/".length(); 76 | int endIndex = classPath.indexOf("/", startIndex); 77 | if (endIndex != -1) { 78 | return classPath.substring(startIndex, endIndex); 79 | } 80 | } 81 | } 82 | } 83 | } 84 | return "Unknown"; 85 | } 86 | } -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Analytics.java: -------------------------------------------------------------------------------- 1 | // /* 2 | // * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | // * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | // * the GNU General Public License as published by the Free Software Foundation, either version 5 | // * 3 of the License. See LICENSE for details 6 | // * 7 | // * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | // * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | // * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | // */ 11 | // package org.example.s3tests; 12 | 13 | // import org.junit.jupiter.api.AfterEach; 14 | // import org.junit.jupiter.api.TestInfo; 15 | // import org.junit.jupiter.api.Tag; 16 | // import org.junit.jupiter.api.Test; 17 | 18 | // class Analytics { 19 | // org.example.test.Analytics test = new org.example.test.Analytics(); 20 | // org.example.testV2.Analytics testV2 = new org.example.testV2.Analytics(); 21 | 22 | // @AfterEach 23 | // void clear(TestInfo testInfo) { 24 | // test.clear(testInfo); 25 | // testV2.clear(testInfo); 26 | // } 27 | 28 | // @Test 29 | // @Tag("Put") 30 | // // 버킷 분석 설정이 가능한지 확인 31 | // void testPutBucketAnalytics() { 32 | // test.testPutBucketAnalytics(); 33 | // testV2.testPutBucketAnalytics(); 34 | // } 35 | 36 | // @Test 37 | // @Tag("Get") 38 | // // 버킷 분석 설정이 올바르게 적용되는지 확인 39 | // void testGetBucketAnalytics() { 40 | // test.testGetBucketAnalytics(); 41 | // testV2.testGetBucketAnalytics(); 42 | // } 43 | 44 | // @Test 45 | // @Tag("Put") 46 | // // 버킷 분석 설정이 여러개 가능한지 확인 47 | // void testAddBucketAnalytics() { 48 | // test.testAddBucketAnalytics(); 49 | // testV2.testAddBucketAnalytics(); 50 | // } 51 | 52 | // @Test 53 | // @Tag("List") 54 | // // 버킷 분석 설정이 목록으로 조회되는지 확인 55 | // void testListBucketAnalytics() { 56 | // test.testListBucketAnalytics(); 57 | // testV2.testListBucketAnalytics(); 58 | // } 59 | 60 | // @Test 61 | // @Tag("Delete") 62 | // // 버킷 분석 설정이 삭제되는지 확인 63 | // void testDeleteBucketAnalytics() { 64 | // test.testDeleteBucketAnalytics(); 65 | // testV2.testDeleteBucketAnalytics(); 66 | // } 67 | 68 | // @Test 69 | // @Tag("Error") 70 | // // 버킷 분석 설정을 잘못 입력했을 때 에러가 발생하는지 확인 71 | // void testPutBucketAnalyticsInvalid() { 72 | // test.testPutBucketAnalyticsInvalid(); 73 | // testV2.testPutBucketAnalyticsInvalid(); 74 | // } 75 | // } 76 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Access.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | class Access { 19 | 20 | org.example.test.Access test = new org.example.test.Access(); 21 | org.example.testV2.Access testV2 = new org.example.testV2.Access(); 22 | 23 | /** 24 | * 테스트 완료 후 정리 작업을 수행합니다. 25 | * @param testInfo 테스트 정보 26 | */ 27 | @AfterEach 28 | void clear(TestInfo testInfo) { 29 | test.clear(testInfo); 30 | testV2.clear(testInfo); 31 | } 32 | 33 | /** 34 | * BlockPublicAcls와 BlockPublicPolicy 접근 권한 블록이 정상적으로 동작하는지 확인하는 테스트 35 | */ 36 | @Test 37 | @Tag("Denied") 38 | void testBlockPublicAclAndPolicy() { 39 | test.testBlockPublicAclAndPolicy(); 40 | testV2.testBlockPublicAclAndPolicy(); 41 | } 42 | 43 | /** 44 | * BlockPublicAcls 접근 권한 블록이 정상적으로 동작하는지 확인하는 테스트 45 | */ 46 | @Test 47 | @Tag("Denied") 48 | void testBlockPublicAcls() { 49 | test.testBlockPublicAcls(); 50 | testV2.testBlockPublicAcls(); 51 | } 52 | 53 | /** 54 | * BlockPublicPolicy 접근 권한 블록이 정상적으로 동작하는지 확인하는 테스트 55 | */ 56 | @Test 57 | @Tag("Denied") 58 | void testBlockPublicPolicy() { 59 | test.testBlockPublicPolicy(); 60 | testV2.testBlockPublicPolicy(); 61 | } 62 | 63 | /** 64 | * 버킷의 접근 권한 블록 삭제 기능을 확인하는 테스트 65 | */ 66 | @Test 67 | @Tag("Check") 68 | void testDeletePublicBlock() { 69 | test.testDeletePublicBlock(); 70 | testV2.testDeletePublicBlock(); 71 | } 72 | 73 | /** 74 | * IgnorePublicAcls 접근 권한 블록이 정상적으로 동작하는지 확인하는 테스트 75 | */ 76 | @Test 77 | @Tag("Denied") 78 | void testIgnorePublicAcls() { 79 | test.testIgnorePublicAcls(); 80 | testV2.testIgnorePublicAcls(); 81 | } 82 | 83 | /** 84 | * 버킷의 접근 권한 블록 설정 기능을 확인하는 테스트 85 | */ 86 | @Test 87 | @Tag("Check") 88 | void testPutPublicBlock() { 89 | test.testPutPublicBlock(); 90 | testV2.testPutPublicBlock(); 91 | } 92 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/Website.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertNull; 15 | 16 | import org.junit.jupiter.api.Test; 17 | import org.junit.jupiter.api.Tag; 18 | 19 | import com.amazonaws.services.s3.model.BucketWebsiteConfiguration; 20 | 21 | public class Website extends TestBase 22 | { 23 | @org.junit.jupiter.api.BeforeAll 24 | public static void beforeAll() 25 | { 26 | System.out.println("Website Start"); 27 | } 28 | 29 | @org.junit.jupiter.api.AfterAll 30 | public static void afterAll() 31 | { 32 | System.out.println("Website End"); 33 | } 34 | 35 | @Test 36 | @Tag("Check") 37 | public void testWebsiteGetBuckets() 38 | { 39 | var client = getClient(); 40 | var bucketName = createBucket(client); 41 | 42 | var response = client.getBucketWebsiteConfiguration(bucketName); 43 | assertNull(response); 44 | } 45 | 46 | @Test 47 | @Tag("Check") 48 | public void testWebsitePutBuckets() 49 | { 50 | var client = getClient(); 51 | var bucketName = createBucket(client); 52 | 53 | var webConfig = new BucketWebsiteConfiguration(); 54 | webConfig.setErrorDocument("HttpStatus.SC_BAD_REQUEST"); 55 | webConfig.setIndexDocumentSuffix("a"); 56 | 57 | client.setBucketWebsiteConfiguration(bucketName, webConfig); 58 | 59 | var response = client.getBucketWebsiteConfiguration(bucketName); 60 | assertEquals(webConfig.getErrorDocument(), response.getErrorDocument()); 61 | } 62 | 63 | @Test 64 | @Tag("Delete") 65 | public void testWebsiteDeleteBuckets() 66 | { 67 | var client = getClient(); 68 | var bucketName = createBucket(client); 69 | 70 | var webConfig = new BucketWebsiteConfiguration(); 71 | webConfig.setErrorDocument("HttpStatus.SC_BAD_REQUEST"); 72 | webConfig.setIndexDocumentSuffix("a"); 73 | 74 | client.setBucketWebsiteConfiguration(bucketName, webConfig); 75 | client.deleteBucketWebsiteConfiguration(bucketName); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Replication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | /** 19 | * 버킷의 복제 기능을 테스트하는 클래스 20 | */ 21 | class Replication { 22 | 23 | org.example.test.Replication test = new org.example.test.Replication(); 24 | org.example.testV2.Replication testV2 = new org.example.testV2.Replication(); 25 | 26 | /** 27 | * 테스트 정리 작업 수행 28 | * @param testInfo 테스트 정보 29 | */ 30 | @AfterEach 31 | void clear(TestInfo testInfo) { 32 | test.clear(testInfo); 33 | testV2.clear(testInfo); 34 | } 35 | 36 | /** 37 | * 버킷의 Replication 설정이 되는지 확인(put/get/delete) 38 | */ 39 | @Test 40 | @Tag("Check") 41 | void testReplicationSet() { 42 | test.testReplicationSet(); 43 | testV2.testReplicationSet(); 44 | } 45 | 46 | /** 47 | * 원본 버킷이 존재하지 않을때 버킷 복제 설정이 실패하는지 확인 48 | */ 49 | @Test 50 | @Tag("ERROR") 51 | void testReplicationInvalidSourceBucketName() { 52 | test.testReplicationInvalidSourceBucketName(); 53 | testV2.testReplicationInvalidSourceBucketName(); 54 | } 55 | 56 | /** 57 | * 원본 버킷의 버저닝 설정이 되어있지 않을때 실패하는지 확인 58 | */ 59 | @Test 60 | @Tag("ERROR") 61 | void testReplicationInvalidSourceBucketVersioning() { 62 | test.testReplicationInvalidSourceBucketVersioning(); 63 | testV2.testReplicationInvalidSourceBucketVersioning(); 64 | } 65 | 66 | /** 67 | * 대상 버킷이 존재하지 않을때 버킷 복제 설정이 실패하는지 확인 68 | */ 69 | @Test 70 | @Tag("ERROR") 71 | void testReplicationInvalidTargetBucketName() { 72 | test.testReplicationInvalidTargetBucketName(); 73 | testV2.testReplicationInvalidTargetBucketName(); 74 | } 75 | 76 | /** 77 | * 대상 버킷의 버저닝 설정이 되어있지 않을때 실패하는지 확인 78 | */ 79 | @Test 80 | @Tag("ERROR") 81 | void testReplicationInvalidTargetBucketVersioning() { 82 | test.testReplicationInvalidTargetBucketVersioning(); 83 | testV2.testReplicationInvalidTargetBucketVersioning(); 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/auth/AWS4SignerForAuthorizationHeader.java: -------------------------------------------------------------------------------- 1 | package org.example.auth; 2 | 3 | import java.net.URL; 4 | import java.util.Date; 5 | import java.util.Map; 6 | 7 | import com.amazonaws.util.BinaryUtils; 8 | 9 | public class AWS4SignerForAuthorizationHeader extends AWS4SignerBase { 10 | 11 | public AWS4SignerForAuthorizationHeader(URL endpointUrl, String httpMethod, String serviceName, String regionName) { 12 | super(endpointUrl, httpMethod, serviceName, regionName); 13 | } 14 | 15 | public String computeSignature(Map headers, Map queryParameters, String bodyHash, String accessKey, String secretKey) { 16 | Date now = new Date(); 17 | String dateTimeStamp = dateTimeFormat.format(now); 18 | 19 | headers.put("x-amz-date", dateTimeStamp); 20 | 21 | String hostHeader = endpointUrl.getHost(); 22 | int port = endpointUrl.getPort(); 23 | if (port > -1) { 24 | hostHeader = hostHeader.concat(":" + Integer.toString(port)); 25 | } 26 | headers.put("Host", hostHeader); 27 | 28 | String canonicalizedHeaderNames = getCanonicalizeHeaderNames(headers); 29 | String canonicalizedHeaders = getCanonicalizedHeaderString(headers); 30 | String canonicalizedQueryParameters = getCanonicalizedQueryString(queryParameters); 31 | String canonicalRequest = getCanonicalRequest(endpointUrl, httpMethod, canonicalizedQueryParameters, canonicalizedHeaderNames, canonicalizedHeaders, bodyHash); 32 | 33 | String dateStamp = dateStampFormat.format(now); 34 | String scope = dateStamp + "/" + regionName + "/" + serviceName + "/" + TERMINATOR; 35 | String stringToSign = getStringToSign(SCHEME, ALGORITHM, dateTimeStamp, scope, canonicalRequest); 36 | 37 | // compute the signing key 38 | byte[] kSecret = (SCHEME + secretKey).getBytes(); 39 | byte[] kDate = sign(dateStamp, kSecret, "HmacSHA256"); 40 | byte[] kRegion = sign(regionName, kDate, "HmacSHA256"); 41 | byte[] kService = sign(serviceName, kRegion, "HmacSHA256"); 42 | byte[] kSigning = sign(TERMINATOR, kService, "HmacSHA256"); 43 | byte[] signature = sign(stringToSign, kSigning, "HmacSHA256"); 44 | 45 | String credentialsAuthorizationHeader = "Credential=" + accessKey + "/" + scope; 46 | String signedHeadersAuthorizationHeader = "SignedHeaders=" + canonicalizedHeaderNames; 47 | String signatureAuthorizationHeader = "Signature=" + BinaryUtils.toHex(signature); 48 | 49 | return SCHEME + "-" + ALGORITHM + " " + credentialsAuthorizationHeader + ", " + signedHeadersAuthorizationHeader + ", " + signatureAuthorizationHeader; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/DeleteBucket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertThrows; 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | 16 | import org.apache.hc.core5.http.HttpStatus; 17 | import org.example.Data.MainData; 18 | import org.junit.jupiter.api.Tag; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import com.amazonaws.AmazonServiceException; 22 | 23 | public class DeleteBucket extends TestBase { 24 | @org.junit.jupiter.api.BeforeAll 25 | public static void beforeAll() { 26 | System.out.println("DeleteBucket Start"); 27 | } 28 | 29 | @org.junit.jupiter.api.AfterAll 30 | public static void afterAll() { 31 | System.out.println("DeleteBucket End"); 32 | } 33 | 34 | @Test 35 | @Tag("ERROR") 36 | public void testBucketDeleteNotExist() { 37 | var client = getClient(); 38 | var bucketName = getNewBucketNameOnly(); 39 | 40 | var e = assertThrows(AmazonServiceException.class, () -> client.deleteBucket(bucketName)); 41 | 42 | assertEquals(HttpStatus.SC_NOT_FOUND, e.getStatusCode()); 43 | assertEquals(MainData.NO_SUCH_BUCKET, e.getErrorCode()); 44 | } 45 | 46 | @Test 47 | @Tag("ERROR") 48 | public void testBucketDeleteNonempty() { 49 | var client = getClient(); 50 | var bucketName = createObjects(client, "foo"); 51 | 52 | var e = assertThrows(AmazonServiceException.class, () -> client.deleteBucket(bucketName)); 53 | 54 | assertEquals(HttpStatus.SC_CONFLICT, e.getStatusCode()); 55 | assertEquals(MainData.BUCKET_NOT_EMPTY, e.getErrorCode()); 56 | } 57 | 58 | @Test 59 | @Tag("ERROR") 60 | public void testBucketCreateDelete() { 61 | var client = getClient(); 62 | var bucketName = createBucket(client); 63 | 64 | client.deleteBucket(bucketName); 65 | 66 | var e = assertThrows(AmazonServiceException.class, () -> client.deleteBucket(bucketName)); 67 | 68 | assertEquals(HttpStatus.SC_NOT_FOUND, e.getStatusCode()); 69 | assertEquals(MainData.NO_SUCH_BUCKET, e.getErrorCode()); 70 | deleteBucketList(bucketName); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/ListBuckets.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | class ListBuckets { 19 | 20 | org.example.test.ListBuckets test = new org.example.test.ListBuckets(); 21 | org.example.testV2.ListBuckets testV2 = new org.example.testV2.ListBuckets(); 22 | 23 | @AfterEach 24 | void clear(TestInfo testInfo) { 25 | test.clear(testInfo); 26 | testV2.clear(testInfo); 27 | } 28 | 29 | /** 30 | * 여러개의 버킷 생성해서 목록 조회 확인 31 | */ 32 | @Test 33 | @Tag("Get") 34 | void testBucketsCreateThenList() { 35 | test.testBucketsCreateThenList(); 36 | testV2.testBucketsCreateThenList(); 37 | } 38 | 39 | /** 40 | * 존재하지 않는 사용자가 버킷목록 조회시 에러 확인 41 | */ 42 | @Test 43 | @Tag("ERROR") 44 | void testListBucketsInvalidAuth() { 45 | test.testListBucketsInvalidAuth(); 46 | testV2.testListBucketsInvalidAuth(); 47 | } 48 | 49 | /** 50 | * 로그인정보를 잘못입력한 사용자가 버킷목록 조회시 에러 확인 51 | */ 52 | @Test 53 | @Tag("ERROR") 54 | void testListBucketsBadAuth() { 55 | test.testListBucketsBadAuth(); 56 | testV2.testListBucketsBadAuth(); 57 | } 58 | 59 | /** 60 | * 버킷의 메타데이터를 가져올 수 있는지 확인 61 | */ 62 | @Test 63 | @Tag("Metadata") 64 | void testHeadBucket() { 65 | test.testHeadBucket(); 66 | testV2.testHeadBucket(); 67 | } 68 | 69 | /** 70 | * 버킷 목록 조회시 Prefix를 이용한 필터링 확인 71 | */ 72 | @Test 73 | @Tag("Prefix") 74 | void testListBucketsPrefix() { 75 | test.testListBucketsPrefix(); 76 | testV2.testListBucketsPrefix(); 77 | } 78 | 79 | /** 80 | * 버킷 목록 조회시 MaxBuckets를 이용한 필터링 확인 81 | */ 82 | @Test 83 | @Tag("MaxBuckets") 84 | void testListBucketsMaxBuckets() { 85 | test.testListBucketsMaxBuckets(); 86 | testV2.testListBucketsMaxBuckets(); 87 | } 88 | 89 | /** 90 | * 버킷 목록 조회시 ContinuationToken를 이용한 필터링 확인 91 | */ 92 | @Test 93 | @Tag("ContinuationToken") 94 | void testListBucketsContinuationToken() { 95 | test.testListBucketsContinuationToken(); 96 | testV2.testListBucketsContinuationToken(); 97 | } 98 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/ObjectData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | import java.util.Date; 14 | 15 | public class ObjectData { 16 | public String bucketName; 17 | public String key; 18 | public String displayName; 19 | public String id; 20 | public String eTag; 21 | public Date lastModified; 22 | public long contentLength; 23 | public String versionId; 24 | 25 | private ObjectData(Builder builder) { 26 | this.bucketName = builder.bucketName; 27 | this.key = builder.key; 28 | this.displayName = builder.displayName; 29 | this.id = builder.id; 30 | this.eTag = builder.eTag; 31 | this.lastModified = builder.lastModified; 32 | this.contentLength = builder.contentLength; 33 | this.versionId = builder.versionId; 34 | } 35 | 36 | public static Builder builder() { 37 | return new Builder(); 38 | } 39 | 40 | public static class Builder { 41 | private String bucketName; 42 | private String key; 43 | private String displayName; 44 | private String id; 45 | private String eTag; 46 | private Date lastModified; 47 | private long contentLength; 48 | private String versionId; 49 | 50 | public Builder bucketName(String bucketName) { 51 | this.bucketName = bucketName; 52 | return this; 53 | } 54 | 55 | public Builder key(String key) { 56 | this.key = key; 57 | return this; 58 | } 59 | 60 | public Builder displayName(String displayName) { 61 | this.displayName = displayName; 62 | return this; 63 | } 64 | 65 | public Builder id(String id) { 66 | this.id = id; 67 | return this; 68 | } 69 | 70 | public Builder eTag(String eTag) { 71 | this.eTag = eTag; 72 | return this; 73 | } 74 | 75 | public Builder lastModified(Date lastModified) { 76 | this.lastModified = lastModified; 77 | return this; 78 | } 79 | 80 | public Builder contentLength(long contentLength) { 81 | this.contentLength = contentLength; 82 | return this; 83 | } 84 | 85 | public Builder versionId(String versionId) { 86 | this.versionId = versionId; 87 | return this; 88 | } 89 | 90 | public ObjectData build() { 91 | return new ObjectData(this); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /java/merge_junit_results.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import glob 4 | import xml.etree.ElementTree as ET 5 | from typing import List 6 | 7 | """Merge multiple JUnit XML files into a single results file. 8 | Output dumps to stdout. 9 | example usage: 10 | $ python merge_junit_results.py results1.xml results2.xml > results.xml 11 | """ 12 | 13 | 14 | def main(): 15 | args = sys.argv[1:] 16 | if not args: 17 | usage() 18 | sys.exit(2) 19 | if "-h" in args or "--help" in args: 20 | usage() 21 | sys.exit(2) 22 | 23 | # Expand wildcards 24 | expanded_args = [] 25 | for arg in args: 26 | expanded_args.extend(glob.glob(arg)) 27 | 28 | merge_results(expanded_args) 29 | 30 | 31 | def merge_results(xml_files: List[str]) -> None: 32 | tests = 0 33 | errors = 0 34 | skipped = 0 35 | failures = 0 36 | time = 0.0 37 | cases = [] 38 | 39 | for file_name in xml_files: 40 | try: 41 | tree = ET.parse(file_name) 42 | test_suite = tree.getroot() 43 | 44 | # 필수 속성이 없을 경우 기본값 0 사용 45 | tests += int(test_suite.attrib.get("tests", 0)) 46 | errors += int(test_suite.attrib.get("errors", 0)) 47 | skipped += int(test_suite.attrib.get("skipped", 0)) 48 | failures += int(test_suite.attrib.get("failures", 0)) 49 | time += float(test_suite.attrib.get("time", 0.0)) 50 | 51 | # properties 요소 제거 52 | for case in test_suite: 53 | for prop in case.findall("properties"): 54 | case.remove(prop) 55 | cases.extend(list(test_suite)) 56 | except ET.ParseError: 57 | print(f"Warning: Failed to parse {file_name}", file=sys.stderr) 58 | continue 59 | 60 | new_root = ET.Element("testsuite") 61 | new_root.attrib["tests"] = str(tests) 62 | new_root.attrib["errors"] = str(errors) 63 | new_root.attrib["skipped"] = str(skipped) 64 | new_root.attrib["failures"] = str(failures) 65 | new_root.attrib["time"] = str(time) 66 | 67 | for case in cases: 68 | new_root.append(case) 69 | 70 | tree = ET.ElementTree(new_root) 71 | 72 | # UTF-8로 인코딩하여 출력 73 | xml_content = ET.tostring(new_root, encoding='utf-8', xml_declaration=True) 74 | if hasattr(sys.stdout, 'buffer'): 75 | sys.stdout.buffer.write(xml_content) 76 | else: 77 | sys.stdout.write(xml_content.decode('utf-8')) 78 | 79 | 80 | def usage(): 81 | print("Usage: python merge_junit_results.py ...") 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/UserData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | public class UserData { 14 | public String displayName; 15 | public String id; 16 | public String email; 17 | public String accessKey; 18 | public String secretKey; 19 | public String kms; 20 | 21 | public UserData() { 22 | displayName = ""; 23 | id = ""; 24 | email = ""; 25 | accessKey = ""; 26 | secretKey = ""; 27 | kms = ""; 28 | } 29 | 30 | public UserData(String displayName, String userId, String email, String accessKey, String secretKey, String kms) { 31 | this.displayName = displayName; 32 | this.id = userId; 33 | this.email = email; 34 | this.accessKey = accessKey; 35 | this.secretKey = secretKey; 36 | this.kms = kms; 37 | } 38 | 39 | public com.amazonaws.services.s3.model.Grantee toGrantee() { 40 | return new com.amazonaws.services.s3.model.CanonicalGrantee(id); 41 | } 42 | 43 | public software.amazon.awssdk.services.s3.model.Grantee toGranteeV2() { 44 | return software.amazon.awssdk.services.s3.model.Grantee.builder() 45 | .id(id) 46 | .type(software.amazon.awssdk.services.s3.model.Type.CANONICAL_USER) 47 | .build(); 48 | } 49 | 50 | public com.amazonaws.services.s3.model.Grant toGrant(com.amazonaws.services.s3.model.Permission permission) { 51 | return new com.amazonaws.services.s3.model.Grant(toGrantee(), permission); 52 | } 53 | 54 | public software.amazon.awssdk.services.s3.model.Grant toGrantV2( 55 | software.amazon.awssdk.services.s3.model.Permission permission) { 56 | return software.amazon.awssdk.services.s3.model.Grant.builder() 57 | .grantee(toGranteeV2()) 58 | .permission(permission) 59 | .build(); 60 | } 61 | 62 | public com.amazonaws.services.s3.model.Owner toOwner() { 63 | return new com.amazonaws.services.s3.model.Owner(id, displayName); 64 | } 65 | 66 | public software.amazon.awssdk.services.s3.model.Owner toOwnerV2() { 67 | return software.amazon.awssdk.services.s3.model.Owner.builder() 68 | .id(id) 69 | .displayName(displayName) 70 | .build(); 71 | } 72 | 73 | public String getArn() { 74 | return "arn:aws:iam::" + id + ":user/" + displayName; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/ObjectDataV2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | import java.time.Instant; 14 | 15 | public class ObjectDataV2 { 16 | public String bucketName; 17 | public String key; 18 | public String displayName; 19 | public String id; 20 | public String eTag; 21 | public Instant lastModified; 22 | public long contentLength; 23 | public String versionId; 24 | 25 | private ObjectDataV2(Builder builder) { 26 | this.bucketName = builder.bucketName; 27 | this.key = builder.key; 28 | this.displayName = builder.displayName; 29 | this.id = builder.id; 30 | this.eTag = builder.eTag; 31 | this.lastModified = builder.lastModified; 32 | this.contentLength = builder.contentLength; 33 | this.versionId = builder.versionId; 34 | } 35 | 36 | public static Builder builder() { 37 | return new Builder(); 38 | } 39 | 40 | public static class Builder { 41 | private String bucketName; 42 | private String key; 43 | private String displayName; 44 | private String id; 45 | private String eTag; 46 | private Instant lastModified; 47 | private long contentLength; 48 | private String versionId; 49 | 50 | public Builder bucketName(String bucketName) { 51 | this.bucketName = bucketName; 52 | return this; 53 | } 54 | 55 | public Builder key(String key) { 56 | this.key = key; 57 | return this; 58 | } 59 | 60 | public Builder displayName(String displayName) { 61 | this.displayName = displayName; 62 | return this; 63 | } 64 | 65 | public Builder id(String id) { 66 | this.id = id; 67 | return this; 68 | } 69 | 70 | public Builder eTag(String eTag) { 71 | this.eTag = eTag; 72 | return this; 73 | } 74 | 75 | public Builder lastModified(Instant lastModified) { 76 | this.lastModified = lastModified; 77 | return this; 78 | } 79 | 80 | public Builder contentLength(long contentLength) { 81 | this.contentLength = contentLength; 82 | return this; 83 | } 84 | 85 | public Builder versionId(String versionId) { 86 | this.versionId = versionId; 87 | return this; 88 | } 89 | 90 | public ObjectDataV2 build() { 91 | return new ObjectDataV2(this); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/testV2/DeleteBucket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.testV2; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertThrows; 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | 16 | import org.apache.hc.core5.http.HttpStatus; 17 | import org.example.Data.MainData; 18 | import org.junit.jupiter.api.Tag; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import software.amazon.awssdk.awscore.exception.AwsServiceException; 22 | 23 | public class DeleteBucket extends TestBase { 24 | @org.junit.jupiter.api.BeforeAll 25 | public static void beforeAll() { 26 | System.out.println("DeleteBucket V2 Start"); 27 | } 28 | 29 | @org.junit.jupiter.api.AfterAll 30 | public static void afterAll() { 31 | System.out.println("DeleteBucket V2 End"); 32 | } 33 | 34 | @Test 35 | @Tag("ERROR") 36 | public void testBucketDeleteNotExist() { 37 | var bucketName = getNewBucketNameOnly(); 38 | var client = getClient(); 39 | 40 | var e = assertThrows(AwsServiceException.class, () -> client.deleteBucket(d -> d.bucket(bucketName))); 41 | 42 | assertEquals(HttpStatus.SC_NOT_FOUND, e.statusCode()); 43 | assertEquals(MainData.NO_SUCH_BUCKET, e.awsErrorDetails().errorCode()); 44 | } 45 | 46 | @Test 47 | @Tag("ERROR") 48 | public void testBucketDeleteNonempty() { 49 | var client = getClient(); 50 | var bucketName = createObjects(client, "foo"); 51 | 52 | var e = assertThrows(AwsServiceException.class, () -> client.deleteBucket(d -> d.bucket(bucketName))); 53 | 54 | assertEquals(HttpStatus.SC_CONFLICT, e.statusCode()); 55 | assertEquals(MainData.BUCKET_NOT_EMPTY, e.awsErrorDetails().errorCode()); 56 | } 57 | 58 | @Test 59 | @Tag("ERROR") 60 | public void testBucketCreateDelete() { 61 | var client = getClient(); 62 | var bucketName = createBucket(client); 63 | 64 | client.deleteBucket(d -> d.bucket(bucketName)); 65 | 66 | var e = assertThrows(AwsServiceException.class, () -> client.deleteBucket(d -> d.bucket(bucketName))); 67 | 68 | assertEquals(HttpStatus.SC_NOT_FOUND, e.statusCode()); 69 | assertEquals(MainData.NO_SUCH_BUCKET, e.awsErrorDetails().errorCode()); 70 | deleteBucketList(bucketName); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dotnet/Test/DeleteBucket.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System; 12 | using System.Collections.Generic; 13 | using System.Net; 14 | using Xunit; 15 | 16 | namespace s3tests 17 | { 18 | public class DeleteBucket : TestBase 19 | { 20 | public DeleteBucket(Xunit.Abstractions.ITestOutputHelper Output) => this.Output = Output; 21 | 22 | [Fact] 23 | [Trait(MainData.Major, "DeleteBucket")] 24 | [Trait(MainData.Minor, "ERROR")] 25 | [Trait(MainData.Explanation, "존재하지 않는 버킷을 삭제하려 했을 경우 실패 확인")] 26 | [Trait(MainData.Result, MainData.ResultFailure)] 27 | public void TestBucketDeleteNotExist() 28 | { 29 | var bucketName = GetNewBucketName(false); 30 | var client = GetClient(); 31 | 32 | var exception = Assert.Throws(() => client.DeleteBucket(bucketName)); 33 | Assert.Equal(HttpStatusCode.NotFound, GetStatus(exception)); 34 | Assert.Equal(MainData.NO_SUCH_BUCKET, GetErrorCode(exception)); 35 | } 36 | [Fact] 37 | [Trait(MainData.Major, "DeleteBucket")] 38 | [Trait(MainData.Minor, "ERROR")] 39 | [Trait(MainData.Explanation, "내용이 비어있지 않은 버킷을 삭제하려 했을 경우 실패 확인")] 40 | [Trait(MainData.Result, MainData.ResultFailure)] 41 | public void TestBucketDeleteNonempty() 42 | { 43 | var bucketName = SetupObjects(new List() { "foo" }); 44 | var client = GetClient(); 45 | 46 | var exception = Assert.Throws(() => client.DeleteBucket(bucketName)); 47 | Assert.Equal(HttpStatusCode.Conflict, GetStatus(exception)); 48 | Assert.Equal(MainData.BUCKET_NOT_EMPTY, GetErrorCode(exception)); 49 | } 50 | 51 | [Fact] 52 | [Trait(MainData.Major, "DeleteBucket")] 53 | [Trait(MainData.Minor, "ERROR")] 54 | [Trait(MainData.Explanation, "이미 삭제된 버킷을 다시 삭제 시도할 경우 실패 확인")] 55 | [Trait(MainData.Result, MainData.ResultFailure)] 56 | public void TestBucketCreateDelete() 57 | { 58 | var client = GetClient(); 59 | var bucketName = GetNewBucket(client); 60 | 61 | client.DeleteBucket(bucketName); 62 | 63 | var exception = Assert.Throws(() => client.DeleteBucket(bucketName)); 64 | Assert.Equal(HttpStatusCode.NotFound, GetStatus(exception)); 65 | Assert.Equal(MainData.NO_SUCH_BUCKET, GetErrorCode(exception)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /dotnet/Test/AES256.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System; 12 | using System.IO; 13 | using System.Linq; 14 | using System.Security.Cryptography; 15 | using System.Text; 16 | 17 | namespace s3tests 18 | { 19 | /// AES256 암호화 클래스 20 | class AES256 21 | { 22 | private const int KEY_SIZE = 32; 23 | private const int VI_SIZE = 16; 24 | private static readonly char[] TEXT = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray(); 25 | 26 | public readonly string Key; 27 | public readonly byte[] ByteKey; 28 | 29 | public readonly string IV; 30 | public readonly byte[] ByteIV; 31 | 32 | public readonly Aes AES; 33 | 34 | public AES256() 35 | { 36 | Key = RandomString(KEY_SIZE); 37 | ByteKey = Encoding.UTF8.GetBytes(Key); 38 | 39 | IV = RandomString(VI_SIZE); 40 | ByteIV = Encoding.UTF8.GetBytes(IV); 41 | 42 | AES = Aes.Create(); 43 | AES.KeySize = 256; 44 | AES.Mode = CipherMode.CBC; 45 | AES.Padding = PaddingMode.PKCS7; 46 | AES.Key = ByteKey; 47 | AES.IV = ByteIV; 48 | } 49 | 50 | public string AESEncrypt(string input) 51 | { 52 | var encrypt = AES.CreateEncryptor(AES.Key, AES.IV); 53 | byte[] buf = null; 54 | using (var ms = new MemoryStream()) 55 | { 56 | using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write)) 57 | { 58 | byte[] xmlBytes = Encoding.UTF8.GetBytes(input); 59 | cs.Write(xmlBytes, 0, xmlBytes.Length); 60 | } 61 | buf = ms.ToArray(); 62 | } 63 | string output = Convert.ToBase64String(buf); 64 | return output; 65 | } 66 | 67 | public string AESDecrypt(string input) 68 | { 69 | var decrypt = AES.CreateDecryptor(); 70 | 71 | using MemoryStream ms = new(); 72 | using CryptoStream cs = new(ms, decrypt, CryptoStreamMode.Write); 73 | byte[] xmlBytes = Convert.FromBase64String(input); 74 | cs.Write(xmlBytes, 0, xmlBytes.Length); 75 | byte[] buf = ms.ToArray(); 76 | string output = Encoding.UTF8.GetString(buf); 77 | return output; 78 | } 79 | 80 | private static string RandomString(int Length) 81 | { 82 | Random rand = new(); 83 | var chars = Enumerable.Range(0, Length).Select(x => TEXT[rand.Next(0, TEXT.Length)]); 84 | return new string(chars.ToArray()); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /dotnet/Test/ListObjectsVersions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System.Collections.Generic; 12 | using Xunit; 13 | 14 | namespace s3tests 15 | { 16 | public class ListObjectsVersions : TestBase 17 | { 18 | public ListObjectsVersions(Xunit.Abstractions.ITestOutputHelper Output) => this.Output = Output; 19 | 20 | [Fact] 21 | [Trait(MainData.Major, "ListObjectsVersions")] 22 | [Trait(MainData.Minor, "Metadata")] 23 | [Trait(MainData.Explanation, "Version정보를 가질 수 있는 버킷에서 ListObjectsVersions로 가져온 Metadata와 " + 24 | "HeadObject, GetObjectAcl로 가져온 Metadata 일치 확인")] 25 | [Trait(MainData.Result, MainData.ResultSuccess)] 26 | public void TestBucketListReturnDataVersioning() 27 | { 28 | var bucketName = GetNewBucket(); 29 | CheckConfigureVersioningRetry(bucketName, Amazon.S3.VersionStatus.Enabled); 30 | var KeyNames = new List() { "bar", "baz", "foo" }; 31 | bucketName = SetupObjects(KeyNames, bucketName: bucketName); 32 | 33 | var Client = GetClient(); 34 | var Data = new List(); 35 | 36 | 37 | foreach (var Key in KeyNames) 38 | { 39 | var ObjResponse = Client.GetObjectMetadata(bucketName, Key); 40 | var ACLResponse = Client.GetObjectACL(bucketName, Key); 41 | 42 | Data.Add(new ObjectData() 43 | { 44 | Key = Key, 45 | DisplayName = ACLResponse.AccessControlList.Owner.DisplayName, 46 | Id = ACLResponse.AccessControlList.Owner.Id, 47 | ETag = ObjResponse.ETag, 48 | LastModified = ObjResponse.LastModified, 49 | ContentLength = ObjResponse.ContentLength, 50 | VersionId = ObjResponse.VersionId 51 | }); 52 | } 53 | 54 | var Response = Client.ListVersions(bucketName); 55 | var ObjList = Response.Versions; 56 | 57 | foreach (var Object in ObjList) 58 | { 59 | var KeyName = Object.Key; 60 | var KeyData = GetObjectToKey(KeyName, Data); 61 | 62 | Assert.NotNull(KeyData); 63 | Assert.Equal(KeyData.ETag, Object.ETag); 64 | Assert.Equal(KeyData.ContentLength, Object.Size); 65 | Assert.Equal(KeyData.DisplayName, Object.Owner.DisplayName); 66 | Assert.Equal(KeyData.Id, Object.Owner.Id); 67 | Assert.Equal(KeyData.VersionId, Object.VersionId); 68 | Assert.Equal(KeyData.LastModified, Object.LastModified.ToUniversalTime()); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dotnet/Test/Website.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3.Model; 12 | using System.Net; 13 | using Xunit; 14 | 15 | namespace s3tests 16 | { 17 | public class Website : TestBase 18 | { 19 | public Website(Xunit.Abstractions.ITestOutputHelper Output) => this.Output = Output; 20 | 21 | [Fact] 22 | [Trait(MainData.Major, "Website")] 23 | [Trait(MainData.Minor, "Check")] 24 | [Trait(MainData.Explanation, "버킷의 Websize 설정 조회 확인")] 25 | [Trait(MainData.Result, MainData.ResultFailure)] 26 | public void TestWebsiteGetBuckets() 27 | { 28 | var client = GetClient(); 29 | var bucketName = GetNewBucket(client); 30 | 31 | var Response = client.GetBucketWebsite(bucketName); 32 | Assert.Equal(HttpStatusCode.NotFound, Response.HttpStatusCode); 33 | } 34 | 35 | [Fact] 36 | [Trait(MainData.Major, "Website")] 37 | [Trait(MainData.Minor, "Check")] 38 | [Trait(MainData.Explanation, "버킷의 Websize 설정이 가능한지 확인")] 39 | [Trait(MainData.Result, MainData.ResultSuccess)] 40 | public void TestWebsitePutBuckets() 41 | { 42 | var client = GetClient(); 43 | var bucketName = GetNewBucket(client); 44 | 45 | var WebConfig = new WebsiteConfiguration() 46 | { 47 | ErrorDocument = "400", 48 | IndexDocumentSuffix = "a" 49 | }; 50 | 51 | var Response = client.PutBucketWebsite(bucketName, WebConfig); 52 | Assert.Equal(HttpStatusCode.OK, Response.HttpStatusCode); 53 | 54 | var GetResponse = client.GetBucketWebsite(bucketName); 55 | Assert.Equal(WebConfig.ErrorDocument, GetResponse.WebsiteConfiguration.ErrorDocument); 56 | } 57 | 58 | [Fact] 59 | [Trait(MainData.Major, "Website")] 60 | [Trait(MainData.Minor, "Delete")] 61 | [Trait(MainData.Explanation, "버킷의 Websize 설정이 삭제가능한지 확인")] 62 | [Trait(MainData.Result, MainData.ResultSuccess)] 63 | public void TestWebsiteDeleteBuckets() 64 | { 65 | var client = GetClient(); 66 | var bucketName = GetNewBucket(client); 67 | 68 | var WebConfig = new WebsiteConfiguration() 69 | { 70 | ErrorDocument = "400", 71 | IndexDocumentSuffix = "a" 72 | }; 73 | 74 | var Response = client.PutBucketWebsite(bucketName, WebConfig); 75 | Assert.Equal(HttpStatusCode.OK, Response.HttpStatusCode); 76 | 77 | var DelResponse = client.DeleteBucketWebsite(bucketName); 78 | Assert.Equal(HttpStatusCode.NoContent, DelResponse.HttpStatusCode); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/auth/AWS4SignerForQueryParameterAuth.java: -------------------------------------------------------------------------------- 1 | package org.example.auth; 2 | 3 | import java.net.URL; 4 | import java.util.Date; 5 | import java.util.Map; 6 | 7 | import com.amazonaws.util.BinaryUtils; 8 | 9 | public class AWS4SignerForQueryParameterAuth extends AWS4SignerBase { 10 | 11 | public AWS4SignerForQueryParameterAuth(URL endpointUrl, String httpMethod, String serviceName, String regionName) { 12 | super(endpointUrl, httpMethod, serviceName, regionName); 13 | } 14 | 15 | public String computeSignature(Map headers, Map parameters, String bodyHash, String accessKey, String secretKey) { 16 | Date now = new Date(); 17 | String dateTimeStamp = dateTimeFormat.format(now); 18 | 19 | String hostHeader = endpointUrl.getHost(); 20 | int port = endpointUrl.getPort(); 21 | if (port > -1) { 22 | hostHeader = hostHeader.concat(":" + Integer.toString(port)); 23 | } 24 | headers.put("Host", hostHeader); 25 | 26 | String canonicalizedHeaderNames = getCanonicalizeHeaderNames(headers); 27 | String canonicalizedHeaders = getCanonicalizedHeaderString(headers); 28 | 29 | String dateStamp = dateStampFormat.format(now); 30 | String scope = dateStamp + "/" + regionName + "/" + serviceName + "/" + TERMINATOR; 31 | 32 | parameters.put("X-Amz-Algorithm", SCHEME + "-" + ALGORITHM); 33 | parameters.put("X-Amz-Credential", accessKey + "/" + scope); 34 | parameters.put("X-Amz-Date", dateTimeStamp); 35 | parameters.put("X-Amz-SignedHeaders", canonicalizedHeaderNames); 36 | 37 | String canonicalizedQueryParameters = getCanonicalizedQueryString(parameters); 38 | String canonicalRequest = getCanonicalRequest(endpointUrl, httpMethod, 39 | canonicalizedQueryParameters, canonicalizedHeaderNames, 40 | canonicalizedHeaders, bodyHash); 41 | 42 | String stringToSign = getStringToSign(SCHEME, ALGORITHM, dateTimeStamp, scope, canonicalRequest); 43 | 44 | byte[] kSecret = (SCHEME + secretKey).getBytes(); 45 | byte[] kDate = sign(dateStamp, kSecret, "HmacSHA256"); 46 | byte[] kRegion = sign(regionName, kDate, "HmacSHA256"); 47 | byte[] kService = sign(serviceName, kRegion, "HmacSHA256"); 48 | byte[] kSigning = sign(TERMINATOR, kService, "HmacSHA256"); 49 | byte[] signature = sign(stringToSign, kSigning, "HmacSHA256"); 50 | 51 | StringBuilder authString = new StringBuilder(); 52 | 53 | authString.append("X-Amz-Algorithm=" + parameters.get("X-Amz-Algorithm")); 54 | authString.append("&X-Amz-Credential=" + parameters.get("X-Amz-Credential")); 55 | authString.append("&X-Amz-Date=" + parameters.get("X-Amz-Date")); 56 | authString.append("&X-Amz-Expires=" + parameters.get("X-Amz-Expires")); 57 | authString.append("&X-Amz-SignedHeaders=" + parameters.get("X-Amz-SignedHeaders")); 58 | authString.append("&X-Amz-Signature=" + BinaryUtils.toHex(signature)); 59 | 60 | return authString.toString(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/DeleteObjects.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | /** 19 | * 오브젝트 삭제 기능 테스트 20 | */ 21 | class DeleteObjects { 22 | 23 | org.example.test.DeleteObjects test = new org.example.test.DeleteObjects(); 24 | org.example.testV2.DeleteObjects testV2 = new org.example.testV2.DeleteObjects(); 25 | 26 | /** 27 | * 테스트 정리 작업 수행 28 | */ 29 | @AfterEach 30 | void clear(TestInfo testInfo) { 31 | test.clear(testInfo); 32 | testV2.clear(testInfo); 33 | } 34 | 35 | /** 36 | * 버킷에 존재하는 오브젝트 여러개를 한번에 삭제 37 | */ 38 | @Test 39 | @Tag("ListObject") 40 | void testMultiObjectDelete() { 41 | test.testMultiObjectDelete(); 42 | testV2.testMultiObjectDelete(); 43 | } 44 | 45 | /** 46 | * 버킷에 존재하는 오브젝트 여러개를 한번에 삭제(ListObjectsV2) 47 | */ 48 | @Test 49 | @Tag("ListObjectsV2") 50 | void testMultiObjectV2Delete() { 51 | test.testMultiObjectV2Delete(); 52 | testV2.testMultiObjectV2Delete(); 53 | } 54 | 55 | /** 56 | * 버킷에 존재하는 버저닝 오브젝트 여러개를 한번에 삭제 57 | */ 58 | @Test 59 | @Tag("Versioning") 60 | void testMultiObjectDeleteVersions() { 61 | test.testMultiObjectDeleteVersions(); 62 | testV2.testMultiObjectDeleteVersions(); 63 | } 64 | 65 | /** 66 | * quiet옵션을 설정한 상태에서 버킷에 존재하는 오브젝트 여러개를 한번에 삭제 67 | */ 68 | @Test 69 | @Tag("quiet") 70 | void testMultiObjectDeleteQuiet() { 71 | test.testMultiObjectDeleteQuiet(); 72 | testV2.testMultiObjectDeleteQuiet(); 73 | } 74 | 75 | /** 76 | * 업로드한 디렉토리를 삭제해도 해당 디렉토리에 오브젝트가 보이는지 확인 77 | */ 78 | @Test 79 | @Tag("Directory") 80 | void testDirectoryDelete() { 81 | test.testDirectoryDelete(); 82 | testV2.testDirectoryDelete(); 83 | } 84 | 85 | /** 86 | * 버저닝 된 버킷에 업로드한 디렉토리를 삭제해도 해당 디렉토리에 오브젝트가 보이는지 확인 87 | */ 88 | @Test 89 | @Tag("versioning") 90 | void testDirectoryDeleteVersions() { 91 | test.testDirectoryDeleteVersions(); 92 | testV2.testDirectoryDeleteVersions(); 93 | } 94 | 95 | /** 96 | * 삭제한 오브젝트가 재대로 삭제 되었는지 확인 97 | */ 98 | @Test 99 | @Tag("DeleteObjects") 100 | void testDeleteObjects() { 101 | test.testDeleteObjects(); 102 | testV2.testDeleteObjects(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Logging.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.Tag; 15 | import org.junit.jupiter.api.Test; 16 | import org.junit.jupiter.api.TestInfo; 17 | 18 | /** 19 | * 버킷의 로깅 기능을 테스트하는 클래스 20 | */ 21 | class Logging { 22 | org.example.test.Logging test = new org.example.test.Logging(); 23 | org.example.testV2.Logging testV2 = new org.example.testV2.Logging(); 24 | 25 | /** 26 | * 테스트 정리 작업 수행 27 | * @param testInfo 테스트 정보 28 | */ 29 | @AfterEach 30 | void clear(TestInfo testInfo) { 31 | test.clear(testInfo); 32 | testV2.clear(testInfo); 33 | } 34 | 35 | /** 36 | * 버킷에 로깅 설정 조회 가능한지 확인 37 | */ 38 | @Test 39 | @Tag("Put/Get") 40 | void testLoggingGet() { 41 | test.testLoggingGet(); 42 | testV2.testLoggingGet(); 43 | } 44 | 45 | /** 46 | * 버킷에 로깅 설정 가능한지 확인 47 | */ 48 | @Test 49 | @Tag("Put/Get") 50 | void testLoggingSet() { 51 | test.testLoggingSet(); 52 | testV2.testLoggingSet(); 53 | } 54 | 55 | /** 56 | * 버킷에 설정한 로깅 정보 조회가 가능한지 확인 57 | */ 58 | @Test 59 | @Tag("Put/Get") 60 | void testLoggingSetGet() { 61 | test.testLoggingSetGet(); 62 | testV2.testLoggingSetGet(); 63 | } 64 | 65 | /** 66 | * 버킷의 로깅에 Prefix가 설정되는지 확인 67 | */ 68 | @Test 69 | @Tag("Put/Get") 70 | void testLoggingPrefix() { 71 | test.testLoggingPrefix(); 72 | testV2.testLoggingPrefix(); 73 | } 74 | 75 | /** 76 | * 버저닝 설정된 버킷의 로깅이 설정되는지 확인 77 | */ 78 | @Test 79 | @Tag("Versioning") 80 | void testLoggingVersioning() { 81 | test.testLoggingVersioning(); 82 | testV2.testLoggingVersioning(); 83 | } 84 | 85 | /** 86 | * SSE-s3설정된 버킷의 로깅이 설정되는지 확인 87 | */ 88 | @Test 89 | @Tag("Encryption") 90 | void testLoggingEncryption() { 91 | test.testLoggingEncryption(); 92 | testV2.testLoggingEncryption(); 93 | } 94 | 95 | /** 96 | * 존재하지 않는 버킷에 로깅 설정 실패 확인 97 | */ 98 | @Test 99 | @Tag("Error") 100 | void testLoggingBucketNotFound() { 101 | test.testLoggingBucketNotFound(); 102 | testV2.testLoggingBucketNotFound(); 103 | } 104 | 105 | /** 106 | * 타깃 버킷이 존재하지 않을때 로깅 설정 실패 확인 107 | */ 108 | @Test 109 | @Tag("Error") 110 | void testLoggingTargetBucketNotFound() { 111 | test.testLoggingTargetBucketNotFound(); 112 | testV2.testLoggingTargetBucketNotFound(); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/testV2/Website.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.testV2; 12 | 13 | import static org.junit.Assert.assertThrows; 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | 16 | import org.apache.hc.core5.http.HttpStatus; 17 | import org.example.Data.MainData; 18 | import org.junit.jupiter.api.Test; 19 | 20 | import software.amazon.awssdk.awscore.exception.AwsServiceException; 21 | import software.amazon.awssdk.services.s3.model.WebsiteConfiguration; 22 | 23 | import org.junit.jupiter.api.Tag; 24 | 25 | public class Website extends TestBase { 26 | @org.junit.jupiter.api.BeforeAll 27 | public static void beforeAll() { 28 | System.out.println("Website V2 Start"); 29 | } 30 | 31 | @org.junit.jupiter.api.AfterAll 32 | public static void afterAll() { 33 | System.out.println("Website V2 End"); 34 | } 35 | 36 | @Test 37 | @Tag("Check") 38 | public void testWebsiteGetBuckets() { 39 | var client = getClient(); 40 | var bucketName = createBucket(client); 41 | 42 | var e = assertThrows(AwsServiceException.class, () -> client.getBucketWebsite(g -> g.bucket(bucketName))); 43 | assertEquals(HttpStatus.SC_NOT_FOUND, e.statusCode()); 44 | assertEquals(MainData.NO_SUCH_WEBSITE_CONFIGURATION, e.awsErrorDetails().errorCode()); 45 | } 46 | 47 | @Test 48 | @Tag("Check") 49 | public void testWebsitePutBuckets() { 50 | var client = getClient(); 51 | var bucketName = createBucket(client); 52 | 53 | var webConfig = WebsiteConfiguration.builder() 54 | .errorDocument(d -> d.key("HttpStatus.SC_BAD_REQUEST")) 55 | .indexDocument(d -> d.suffix("a")) 56 | .build(); 57 | 58 | client.putBucketWebsite(g -> g.bucket(bucketName).websiteConfiguration(webConfig)); 59 | 60 | var response = client.getBucketWebsite(g -> g.bucket(bucketName)); 61 | assertEquals(webConfig.errorDocument(), response.errorDocument()); 62 | assertEquals(webConfig.indexDocument(), response.indexDocument()); 63 | } 64 | 65 | @Test 66 | @Tag("Delete") 67 | public void testWebsiteDeleteBuckets() { 68 | var client = getClient(); 69 | var bucketName = createBucket(client); 70 | 71 | var webConfig = WebsiteConfiguration.builder() 72 | .errorDocument(d -> d.key("HttpStatus.SC_BAD_REQUEST")) 73 | .indexDocument(d -> d.suffix("a")) 74 | .build(); 75 | 76 | client.putBucketWebsite(g -> g.bucket(bucketName).websiteConfiguration(webConfig)); 77 | client.deleteBucketWebsite(d -> d.bucket(bucketName)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Utils/ReplicationTest/Utility.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3.Model; 12 | using Amazon.S3; 13 | using log4net; 14 | using System; 15 | using System.IO; 16 | using System.Linq; 17 | using System.Net; 18 | using System.Reflection; 19 | 20 | namespace ReplicationTest 21 | { 22 | class Utility 23 | { 24 | private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 25 | private static readonly char[] TEXT = "abcdefghijklmnopqrstuvwxyz0123456789".ToCharArray(); 26 | private static readonly char[] TEXT_STRING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray(); 27 | 28 | public static bool CreateDummyFile(string FilePath, int FileSize) 29 | { 30 | try 31 | { 32 | if (new FileInfo(FilePath).Exists) File.Delete(FilePath); 33 | FileStream fs = new FileStream(FilePath, FileMode.CreateNew); 34 | fs.Seek(FileSize, SeekOrigin.Begin); 35 | fs.WriteByte(0); 36 | fs.Close(); 37 | return true; 38 | } 39 | catch (Exception e) 40 | { 41 | log.Error(e); 42 | return false; 43 | } 44 | } 45 | 46 | public static bool CheckFile(string FilePath) 47 | { 48 | try 49 | { 50 | if (new FileInfo(FilePath).Exists) return true; 51 | } 52 | catch (Exception e) 53 | { 54 | log.Error(e); 55 | } 56 | return false; 57 | } 58 | 59 | public static string RandomText(int Length) 60 | { 61 | Random rand = new Random(Guid.NewGuid().GetHashCode()); 62 | var chars = Enumerable.Range(0, Length).Select(x => TEXT[rand.Next(0, TEXT.Length)]); 63 | return new string(chars.ToArray()); 64 | } 65 | public static string RandomTextToLong(int Length) 66 | { 67 | Random rand = new Random(Guid.NewGuid().GetHashCode()); 68 | var chars = Enumerable.Range(0, Length).Select(x => TEXT_STRING[rand.Next(0, TEXT_STRING.Length)]); 69 | return new string(chars.ToArray()); 70 | } 71 | 72 | public static HttpStatusCode GetStatus(AggregateException e) 73 | { 74 | if (e.InnerException is AmazonS3Exception e2) return e2.StatusCode; 75 | return HttpStatusCode.OK; 76 | } 77 | public static string GetErrorCode(AggregateException e) 78 | { 79 | if (e.InnerException is AmazonS3Exception e2) return e2.ErrorCode; 80 | return null; 81 | } 82 | public static string GetBody(GetObjectResponse Response) 83 | { 84 | string Body = string.Empty; 85 | if (Response != null && Response.ResponseStream != null) 86 | { 87 | var Reader = new StreamReader(Response.ResponseStream); 88 | Body = Reader.ReadToEnd(); 89 | Reader.Close(); 90 | } 91 | return Body; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /dotnet/s3tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | 6 | false 7 | 8 | AnyCPU;x64 9 | 10 | 11 | 12 | bin\ 13 | 14 | 15 | 16 | bin\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | all 27 | runtime; build; native; contentfiles; analyzers; buildtransitive 28 | 29 | 30 | 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | PreserveNewest 43 | 44 | 45 | PreserveNewest 46 | 47 | 48 | PreserveNewest 49 | 50 | 51 | PreserveNewest 52 | 53 | 54 | PreserveNewest 55 | 56 | 57 | PreserveNewest 58 | 59 | 60 | PreserveNewest 61 | 62 | 63 | PreserveNewest 64 | 65 | 66 | PreserveNewest 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | PreserveNewest 76 | 77 | 78 | PreserveNewest 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /dotnet/Test/ListBuckets.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using System; 12 | using System.Collections.Generic; 13 | using System.Net; 14 | using Xunit; 15 | 16 | namespace s3tests 17 | { 18 | public class ListBuckets : TestBase 19 | { 20 | public ListBuckets(Xunit.Abstractions.ITestOutputHelper Output) => this.Output = Output; 21 | 22 | [Fact] 23 | [Trait(MainData.Major, "ListBuckets")] 24 | [Trait(MainData.Minor, "Get")] 25 | [Trait(MainData.Explanation, "여러개의 버킷 생성해서 목록 조회 확인")] 26 | [Trait(MainData.Result, MainData.ResultSuccess)] 27 | public void TestBucketsCreateThenList() 28 | { 29 | var Client = GetClient(); 30 | var BucketNames = new List(); 31 | for (int i = 0; i < 5; i++) 32 | { 33 | var bucketName = GetNewBucketName(); 34 | Client.PutBucket(bucketName); 35 | BucketNames.Add(bucketName); 36 | } 37 | 38 | var Response = Client.ListBuckets(); 39 | var BucketList = GetBucketList(Response); 40 | 41 | foreach (var bucketName in BucketNames) 42 | { 43 | if (!BucketList.Contains(bucketName)) 44 | throw new Exception(string.Format("S3 implementation's GET on Service did not return bucket we created: {0}", bucketName)); 45 | } 46 | } 47 | 48 | [Fact] 49 | [Trait(MainData.Major, "ListBuckets")] 50 | [Trait(MainData.Minor, "ERROR")] 51 | [Trait(MainData.Explanation, "존재하지 않는 사용자가 버킷목록 조회시 에러 확인")] 52 | [Trait(MainData.Result, MainData.ResultFailure)] 53 | public void TestListBucketsInvalidAuth() 54 | { 55 | var BadAuthClient = GetBadAuthClient(); 56 | var e = Assert.Throws(() => BadAuthClient.ListBuckets()); 57 | Assert.Equal(HttpStatusCode.Forbidden, GetStatus(e)); 58 | Assert.Equal(MainData.INVALID_ACCESS_KEY_ID, GetErrorCode(e)); 59 | } 60 | 61 | [Fact] 62 | [Trait(MainData.Major, "ListBuckets")] 63 | [Trait(MainData.Minor, "ERROR")] 64 | [Trait(MainData.Explanation, "로그인정보를 잘못입력한 사용자가 버킷목록 조회시 에러 확인")] 65 | [Trait(MainData.Result, MainData.ResultFailure)] 66 | public void TestListBucketsBadAuth() 67 | { 68 | var MainAccessKey = Config.MainUser.AccessKey; 69 | var BadAuthClient = GetBadAuthClient(accessKey: MainAccessKey); 70 | 71 | var e = Assert.Throws(() => BadAuthClient.ListBuckets()); 72 | Assert.Equal(HttpStatusCode.Forbidden, GetStatus(e)); 73 | Assert.Equal(MainData.SIGNATURE_DOES_NOT_MATCH, GetErrorCode(e)); 74 | } 75 | 76 | [Fact] 77 | [Trait(MainData.Major, "ListBuckets")] 78 | [Trait(MainData.Minor, "Metadata")] 79 | [Trait(MainData.Explanation, "버킷의 메타데이터를 가져올 수 있는지 확인")] 80 | [Trait(MainData.Result, MainData.ResultFailure)] 81 | public void TestHeadBucket() 82 | { 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /python/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | #the GNU General Public License as published by the Free Software Foundation, either version 5 | #3 of the License. See LICENSE for details 6 | 7 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | 11 | ## Check the arguments when execute the script 12 | if [ "$#" -eq 0 ] 13 | then 14 | echo " 15 | Error: Arguments missing! 16 | Usage: ./[script] [arg1] 17 | arg1 'a' : run all tests 18 | e.g., $ $0 a 19 | 'f' : run failed tests again 20 | e.g., $ $0 f 21 | 'l' : show tests list with test-id 22 | e.g., $ $0 l 23 | 'n' : run test using test-id 24 | e.g., $ $0 n 97 25 | 'c' : run tests with specific class 26 | e.g., $ $0 c SSE_C 27 | 'w' : run test with specific att. 'major' & 'minor' 28 | e.g., $ $0 w \"ListObjectsV2\" \"Delimiter and Prefix\" 29 | 't' : run tests with specific att. 'minor' 30 | e.g., $ $0 t \"Multi thread\" 31 | " 32 | exit 1 33 | fi 34 | 35 | ## Common settings 36 | vConfig="./sample.conf" 37 | vResult_file="./Report/result_"$vMajor"_"$vMinor"_" 38 | 39 | ## Execute nosetests & generate the report with html form 40 | vDate=`date +%Y%m%d%H%M` 41 | vResult_file+=$vDate 42 | vResult_file+=".html" 43 | 44 | ## 45 | case "$1" in 46 | "a") 47 | echo "#### Run all tests #########################" 48 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws' --with-id --id-file=mylist --with-html --html-file=$vResult_file s3tests_boto3.functional.test_s3` 49 | ;; 50 | "f") 51 | echo "#### Run failed tests ######################" 52 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --failed --nologcapture -a '!fails_on_aws' --with-id --id-file=mylist --with-html --html-file=$vResult_file s3tests_boto3.functional.test_s3` 53 | ;; 54 | "l") 55 | echo "#### Test list with test-id ################" 56 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws' --collect-only --with-id --id-file=mylist s3tests_boto3.functional.test_s3` 57 | ;; 58 | "n") 59 | echo "#### Run tests using test-id ###############" 60 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws' --with-id --id-file=mylist --with-html --html-file=$vResult_file $2` 61 | ;; 62 | "c") 63 | echo "#### Run tests with specific class ##########" 64 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws' --with-id --id-file=mylist --with-html --html-file=$vResult_file s3tests_boto3.functional.test_s3:$2` 65 | ;; 66 | "w") 67 | echo "#### Run test with specific attr. 'major' & 'minor' ##########" 68 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws','major='"$2",'minor='"$3" --with-id --id-file=mylist --with-html --html-file=$vResult_file s3tests_boto3.functional.test_s3` 69 | ;; 70 | "t") 71 | echo "#### Run tests with specific attr. ##########" 72 | result=`S3TEST_CONF=$vConfig ./virtualenv/bin/nosetests -v --nologcapture -a '!fails_on_aws','minor='"$2" --with-id --id-file=mylist --with-html --html-file=$vResult_file s3tests_boto3.functional.test_s3` 73 | esac 74 | -------------------------------------------------------------------------------- /python/s3tests_boto3/functional/rgw_interactive.py: -------------------------------------------------------------------------------- 1 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 2 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 3 | #the GNU General Public License as published by the Free Software Foundation, either version 4 | #3 of the License. See LICENSE for details 5 | 6 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 7 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 8 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 9 | #!/usr/bin/python 10 | import boto3 11 | import os 12 | import random 13 | import string 14 | import itertools 15 | 16 | host = "127.0.0.1" 17 | port = 8080 18 | 19 | ## AWS access key 20 | access_key = "123456789" 21 | 22 | ## AWS secret key 23 | secret_key = "123456789" 24 | 25 | prefix = "my-test-" 26 | 27 | endpoint_url = "http://%s:%d" % (host, port) 28 | 29 | client = boto3.client(service_name='s3', 30 | aws_access_key_id=access_key, 31 | aws_secret_access_key=secret_key, 32 | endpoint_url=endpoint_url, 33 | use_ssl=False, 34 | verify=False) 35 | 36 | s3 = boto3.resource('s3', 37 | use_ssl=False, 38 | verify=False, 39 | endpoint_url=endpoint_url, 40 | aws_access_key_id=access_key, 41 | aws_secret_access_key=secret_key) 42 | 43 | def choose_bucket_prefix(template, max_len=30): 44 | """ 45 | Choose a prefix for our test buckets, so they're easy to identify. 46 | 47 | Use template and feed it more and more random filler, until it's 48 | as long as possible but still below max_len. 49 | """ 50 | rand = ''.join( 51 | random.choice(string.ascii_lowercase + string.digits) 52 | for c in range(255) 53 | ) 54 | 55 | while rand: 56 | s = template.format(random=rand) 57 | if len(s) <= max_len: 58 | return s 59 | rand = rand[:-1] 60 | 61 | raise RuntimeError( 62 | 'Bucket prefix template is impossible to fulfill: {template!r}'.format( 63 | template=template, 64 | ), 65 | ) 66 | 67 | bucket_counter = itertools.count(1) 68 | 69 | def get_new_bucket_name(): 70 | """ 71 | Get a bucket name that probably does not exist. 72 | 73 | We make every attempt to use a unique random prefix, so if a 74 | bucket by this name happens to exist, it's ok if tests give 75 | false negatives. 76 | """ 77 | name = '{prefix}{num}'.format( 78 | prefix=prefix, 79 | num=next(bucket_counter), 80 | ) 81 | return name 82 | 83 | def get_new_bucket(session=boto3, name=None, headers=None): 84 | """ 85 | Get a bucket that exists and is empty. 86 | 87 | Always recreates a bucket from scratch. This is useful to also 88 | reset ACLs and such. 89 | """ 90 | s3 = session.resource('s3', 91 | use_ssl=False, 92 | verify=False, 93 | endpoint_url=endpoint_url, 94 | aws_access_key_id=access_key, 95 | aws_secret_access_key=secret_key) 96 | if name is None: 97 | name = get_new_bucket_name() 98 | bucket = s3.Bucket(name) 99 | bucket_location = bucket.create() 100 | return bucket 101 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Utility/CheckSum.java: -------------------------------------------------------------------------------- 1 | package org.example.Utility; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.util.Base64; 5 | import java.util.List; 6 | 7 | import software.amazon.awssdk.checksums.SdkChecksum; 8 | import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm; 9 | 10 | public class CheckSum { 11 | 12 | private CheckSum() { 13 | } // utility class이므로 인스턴스화 방지 14 | 15 | /** 16 | * 문자열에 대한 체크섬 계산 17 | */ 18 | public static String calculateChecksum(ChecksumAlgorithm algorithm, String content) { 19 | return Base64.getEncoder().encodeToString(calculateChecksumBytes(algorithm, content)); 20 | } 21 | 22 | /** 23 | * List에 대한 체크섬 계산 24 | */ 25 | public static String calculateChecksum(ChecksumAlgorithm algorithm, List contents) { 26 | return Base64.getEncoder().encodeToString(calculateChecksumBytes(algorithm, contents)) + "-" + contents.size(); 27 | } 28 | 29 | /** 30 | * 문자열에 대한 체크섬 bytes 반환 31 | */ 32 | public static byte[] calculateChecksumBytes(ChecksumAlgorithm algorithm, String content) { 33 | SdkChecksum hasher = SdkChecksum.forAlgorithm(S3ChecksumAlgorithm.withAlgorithm(algorithm)); 34 | hasher.update(content.getBytes(StandardCharsets.UTF_8)); 35 | return hasher.getChecksumBytes(); 36 | } 37 | 38 | /** 39 | * List에 대한 체크섬 bytes 반환 40 | */ 41 | public static byte[] calculateChecksumBytes(ChecksumAlgorithm algorithm, List contents) { 42 | SdkChecksum hasher = SdkChecksum.forAlgorithm(S3ChecksumAlgorithm.withAlgorithm(algorithm)); 43 | for (byte[] content : contents) { 44 | hasher.update(content); 45 | } 46 | return hasher.getChecksumBytes(); 47 | } 48 | 49 | /** 50 | * List에 대한 체크섬 계산 51 | */ 52 | public static String calculateChecksumByBase64(ChecksumAlgorithm algorithm, List contents) { 53 | return calculateChecksum(algorithm, contents.stream().map(Base64.getDecoder()::decode).toList()); 54 | } 55 | 56 | /** 57 | * List에 대한 체크섬 계산 58 | */ 59 | public static String combineChecksumByBase64(ChecksumAlgorithm algorithm, long partSize, List contents) { 60 | byte[] crc1 = Base64.getDecoder().decode(contents.get(0)); 61 | 62 | for (var index = 1; index < contents.size(); index++) { 63 | byte[] crc2 = Base64.getDecoder().decode(contents.get(index)); 64 | crc1 = CrcCombine.combinebytes(crc1, crc2, partSize, algorithm); 65 | } 66 | return Base64.getEncoder().encodeToString(crc1); 67 | } 68 | 69 | /** 70 | * List에 대한 CRC32 체크섬 계산 71 | */ 72 | public static String crc32(List contents) { 73 | return calculateChecksum(ChecksumAlgorithm.CRC32, contents); 74 | } 75 | 76 | /** 77 | * List에 대한 CRC32C 체크섬 계산 78 | */ 79 | public static String crc32c(List contents) { 80 | return calculateChecksum(ChecksumAlgorithm.CRC32_C, contents); 81 | } 82 | 83 | /** 84 | * List에 대한 CRC64 체크섬 계산 85 | */ 86 | public static String crc64Nvme(List contents) { 87 | return calculateChecksum(ChecksumAlgorithm.CRC64_NVME, contents); 88 | } 89 | 90 | /** 91 | * List에 대한 SHA1 체크섬 계산 92 | */ 93 | public static String sha1(List contents) { 94 | return calculateChecksum(ChecksumAlgorithm.SHA1, contents); 95 | } 96 | 97 | /** 98 | * List에 대한 SHA256 체크섬 계산 99 | */ 100 | public static String sha256(List contents) { 101 | return calculateChecksum(ChecksumAlgorithm.SHA256, contents); 102 | } 103 | } -------------------------------------------------------------------------------- /python/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | #KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | #the GNU General Public License as published by the Free Software Foundation, either version 5 | #3 of the License. See LICENSE for details 6 | 7 | #본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | #KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | #KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | set -e 11 | 12 | virtualenv="virtualenv" 13 | declare -a packages 14 | source /etc/os-release 15 | 16 | case "$ID" in 17 | debian|ubuntu|devuan) 18 | packages=(debianutils python3-pip python3-virtualenv python3-dev libevent-dev libffi-dev libxml2-dev libxslt-dev zlib1g-dev) 19 | for package in ${packages[@]}; do 20 | if [ "$(dpkg --status -- $package 2>/dev/null|sed -n 's/^Status: //p')" != "install ok installed" ]; then 21 | # add a space after old values 22 | missing="${missing:+$missing }$package" 23 | fi 24 | done 25 | 26 | if [ -n "$missing" ]; then 27 | echo "$0: missing required DEB packages. Installing via sudo." 1>&2 28 | sudo apt-get -y install $missing 29 | fi 30 | ;; 31 | centos|fedora|rhel|ol|virtuozzo) 32 | 33 | packages=(which python3-virtualenv python36-devel libevent-devel libffi-devel libxml2-devel libxslt-devel zlib-devel) 34 | for package in ${packages[@]}; do 35 | # When the package is python36-devel we change it to python3-devel on Fedora 36 | if [[ ${package} == "python36-devel" && -f /etc/fedora-release ]]; then 37 | package=python36 38 | fi 39 | if [ "$(rpm -qa $package 2>/dev/null)" == "" ]; then 40 | missing="${missing:+$missing }$package" 41 | fi 42 | done 43 | 44 | if [ -n "$missing" ]; then 45 | echo "$0: Missing required RPM packages: ${missing}." 1>&2 46 | sudo yum -y install $missing 47 | fi 48 | ;; 49 | opensuse*|suse|sles) 50 | 51 | packages=(which python3-virtualenv python3-devel libev-devel libffi-devel libxml2-devel libxslt-devel zlib-devel) 52 | for package in ${packages[@]}; do 53 | if [ "$(rpm -qa $package 2>/dev/null)" == "" ]; then 54 | missing="${missing:+$missing }$package" 55 | fi 56 | if [ -n "$missing" ]; then 57 | echo "$0: Missing required RPM packages: ${missing}." 1>&2 58 | sudo zypper --non-interactive install --no-recommends $missing 59 | fi 60 | done 61 | 62 | ;; 63 | *) 64 | echo "Bootstrap script does not support this distro yet, consider adding the packages" 65 | exit 1 66 | esac 67 | 68 | 69 | # s3-tests only works on python 3.6 not newer versions of python3 70 | ${virtualenv} --python=$(which python3.6) virtualenv 71 | 72 | # avoid pip bugs 73 | ./virtualenv/bin/pip3 install --upgrade pip 74 | 75 | # latest setuptools supporting python 2.7 76 | ./virtualenv/bin/pip install setuptools==44.1.0 77 | 78 | ./virtualenv/bin/pip3 install -r requirements.txt 79 | 80 | # forbid setuptools from using the network because it'll try to use 81 | # easy_install, and we really wanted pip; next line will fail if pip 82 | # requirements.txt does not match setup.py requirements -- sucky but 83 | # good enough for now 84 | ./virtualenv/bin/python3 setup.py develop 85 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/Data/AES256.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.Data; 12 | 13 | import java.nio.ByteBuffer; 14 | import java.nio.charset.StandardCharsets; 15 | import java.security.AlgorithmParameters; 16 | import java.security.SecureRandom; 17 | import java.util.Base64; 18 | 19 | import javax.crypto.Cipher; 20 | import javax.crypto.SecretKey; 21 | import javax.crypto.SecretKeyFactory; 22 | import javax.crypto.spec.IvParameterSpec; 23 | import javax.crypto.spec.PBEKeySpec; 24 | import javax.crypto.spec.SecretKeySpec; 25 | 26 | public class AES256 { 27 | static final String CBC_MODE = "AES/CBC/PKCS5Padding"; 28 | 29 | public static String encrypt(String msg, String key) throws Exception { 30 | 31 | var random = new SecureRandom(); 32 | var bytes = new byte[20]; 33 | random.nextBytes(bytes); 34 | var saltBytes = bytes; 35 | 36 | // Password-Based Key Derivation function 2 37 | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 38 | 39 | PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256); 40 | 41 | SecretKey secretKey = factory.generateSecret(spec); 42 | SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); 43 | 44 | // CBC : Cipher Block Chaining Mode 45 | Cipher cipher = Cipher.getInstance(CBC_MODE); 46 | cipher.init(Cipher.ENCRYPT_MODE, secret); 47 | 48 | AlgorithmParameters params = cipher.getParameters(); 49 | 50 | byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); 51 | byte[] encryptedTextBytes = cipher.doFinal(msg.getBytes(StandardCharsets.UTF_8)); 52 | byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length]; 53 | System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length); 54 | System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length); 55 | System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length); 56 | 57 | return Base64.getEncoder().encodeToString(buffer); 58 | } 59 | 60 | public static String decrypt(String msg, String key) throws Exception { 61 | 62 | Cipher cipher = Cipher.getInstance(CBC_MODE); 63 | ByteBuffer buffer = ByteBuffer.wrap(Base64.getDecoder().decode(msg)); 64 | 65 | byte[] saltBytes = new byte[20]; 66 | buffer.get(saltBytes, 0, saltBytes.length); 67 | byte[] ivBytes = new byte[cipher.getBlockSize()]; 68 | buffer.get(ivBytes, 0, ivBytes.length); 69 | byte[] encryptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes.length]; 70 | buffer.get(encryptedTextBytes); 71 | 72 | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 73 | PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256); 74 | 75 | SecretKey secretKey = factory.generateSecret(spec); 76 | SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); 77 | 78 | cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); 79 | 80 | byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes); 81 | return new String(decryptedTextBytes); 82 | } 83 | } -------------------------------------------------------------------------------- /java/src/main/java/org/example/testV2/Accelerate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.testV2; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertThrows; 15 | 16 | import org.junit.jupiter.api.Tag; 17 | import org.junit.jupiter.api.Test; 18 | import org.apache.hc.core5.http.HttpStatus; 19 | 20 | import software.amazon.awssdk.awscore.exception.AwsServiceException; 21 | import software.amazon.awssdk.services.s3.model.BucketAccelerateStatus; 22 | 23 | import org.junit.jupiter.api.parallel.Execution; 24 | import org.junit.jupiter.api.parallel.ExecutionMode; 25 | 26 | @Execution(ExecutionMode.CONCURRENT) 27 | public class Accelerate extends TestBase { 28 | @org.junit.jupiter.api.BeforeAll 29 | public static void beforeAll() { 30 | System.out.println("Accelerate V2 Start"); 31 | } 32 | 33 | @org.junit.jupiter.api.AfterAll 34 | public static void afterAll() { 35 | System.out.println("Accelerate V2 End"); 36 | } 37 | 38 | @Test 39 | @Tag("Put") 40 | public void testPutBucketAccelerate() { 41 | var client = getClient(); 42 | var bucketName = createBucket(client); 43 | 44 | client.putBucketAccelerateConfiguration( 45 | p -> p.bucket(bucketName).accelerateConfiguration(a -> a.status("Enabled"))); 46 | } 47 | 48 | @Test 49 | @Tag("Get") 50 | public void testGetBucketAccelerate() { 51 | var client = getClient(); 52 | var bucketName = createBucket(client); 53 | 54 | client.putBucketAccelerateConfiguration(p -> p.bucket(bucketName) 55 | .accelerateConfiguration(a -> a.status(BucketAccelerateStatus.ENABLED))); 56 | 57 | var response = client.getBucketAccelerateConfiguration(g -> g 58 | .bucket(bucketName)); 59 | assertEquals(BucketAccelerateStatus.ENABLED, response.status()); 60 | } 61 | 62 | @Test 63 | @Tag("Change") 64 | public void testChangeBucketAccelerate() { 65 | var client = getClient(); 66 | var bucketName = createBucket(client); 67 | 68 | client.putBucketAccelerateConfiguration(p -> p 69 | .bucket(bucketName) 70 | .accelerateConfiguration(a -> a.status(BucketAccelerateStatus.ENABLED))); 71 | 72 | var response = client.getBucketAccelerateConfiguration(g -> g 73 | .bucket(bucketName)); 74 | assertEquals(BucketAccelerateStatus.ENABLED, response.status()); 75 | 76 | client.putBucketAccelerateConfiguration(p -> p 77 | .bucket(bucketName) 78 | .accelerateConfiguration(a -> a.status(BucketAccelerateStatus.SUSPENDED))); 79 | 80 | response = client.getBucketAccelerateConfiguration(g -> g 81 | .bucket(bucketName)); 82 | assertEquals(BucketAccelerateStatus.SUSPENDED, response.status()); 83 | } 84 | 85 | @Test 86 | @Tag("Error") 87 | public void testPutBucketAccelerateInvalid() { 88 | var client = getClient(); 89 | var bucketName = createBucket(client); 90 | 91 | var e = assertThrows(AwsServiceException.class, 92 | () -> client.putBucketAccelerateConfiguration(p -> p 93 | .bucket(bucketName) 94 | .accelerateConfiguration(a -> a.status("Invalid")))); 95 | assertEquals(HttpStatus.SC_BAD_REQUEST, e.statusCode()); 96 | assertEquals("MalformedXML", e.awsErrorDetails().errorCode()); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/Metrics.java: -------------------------------------------------------------------------------- 1 | package org.example.s3tests; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.Tag; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.TestInfo; 7 | 8 | /** 9 | * 버킷의 메트릭스 기능을 테스트하는 클래스 10 | */ 11 | class Metrics { 12 | org.example.test.Metrics test = new org.example.test.Metrics(); 13 | org.example.testV2.Metrics testV2 = new org.example.testV2.Metrics(); 14 | 15 | /** 16 | * 테스트 정리 작업 수행 17 | * @param testInfo 테스트 정보 18 | */ 19 | @AfterEach 20 | void clear(TestInfo testInfo) { 21 | test.clear(testInfo); 22 | testV2.clear(testInfo); 23 | } 24 | 25 | /** 26 | * 버킷에 Metrics를 설정하지 않은 상태에서 조회가 가능한지 확인 27 | */ 28 | @Test 29 | @Tag("List") 30 | void testMetrics() { 31 | test.testMetrics(); 32 | testV2.testMetrics(); 33 | } 34 | 35 | /** 36 | * 버킷에 Metrics를 설정할 수 있는지 확인 37 | */ 38 | @Test 39 | @Tag("Put") 40 | void testPutMetrics() { 41 | test.testPutMetrics(); 42 | testV2.testPutMetrics(); 43 | } 44 | 45 | /** 46 | * 버킷에 Metrics 설정이 되었는지 확인 47 | */ 48 | @Test 49 | @Tag("Check") 50 | void testCheckMetrics() { 51 | test.testCheckMetrics(); 52 | testV2.testCheckMetrics(); 53 | } 54 | 55 | /** 56 | * 버킷에 설정된 Metrics를 조회할 수 있는지 확인 57 | */ 58 | @Test 59 | @Tag("Get") 60 | void testGetMetrics() { 61 | test.testGetMetrics(); 62 | testV2.testGetMetrics(); 63 | } 64 | 65 | /** 66 | * 버킷에 설정된 Metrics를 삭제할 수 있는지 확인 67 | */ 68 | @Test 69 | @Tag("Delete") 70 | void testDeleteMetrics() { 71 | test.testDeleteMetrics(); 72 | testV2.testDeleteMetrics(); 73 | } 74 | 75 | /** 76 | * 존재하지 않은 Metrics를 가져오려고 할 경우 실패하는지 확인 77 | */ 78 | @Test 79 | @Tag("Error") 80 | void testGetMetricsNotExist() { 81 | test.testGetMetricsNotExist(); 82 | testV2.testGetMetricsNotExist(); 83 | } 84 | 85 | /** 86 | * 존재하지 않은 Metrics를 삭제하려고 할 경우 실패하는지 확인 87 | */ 88 | @Test 89 | @Tag("Error") 90 | void testDeleteMetricsNotExist() { 91 | test.testDeleteMetricsNotExist(); 92 | testV2.testDeleteMetricsNotExist(); 93 | } 94 | 95 | /** 96 | * 존재하지 않은 Metrics를 설정하려고 할 경우 실패하는지 확인 97 | */ 98 | @Test 99 | @Tag("Error") 100 | void testPutMetricsNotExist() { 101 | test.testPutMetricsNotExist(); 102 | testV2.testPutMetricsNotExist(); 103 | } 104 | 105 | /** 106 | * Metrics 아이디를 빈값으로 설정하려고 할 경우 실패하는지 확인 107 | */ 108 | @Test 109 | @Tag("Error") 110 | void testPutMetricsEmptyId() { 111 | test.testPutMetricsEmptyId(); 112 | testV2.testPutMetricsEmptyId(); 113 | } 114 | 115 | /** 116 | * Metrics 아이디를 설정하지 않고 설정하려고 할 경우 실패하는지 확인 117 | */ 118 | @Test 119 | @Tag("Error") 120 | void testPutMetricsNoId() { 121 | test.testPutMetricsNoId(); 122 | testV2.testPutMetricsNoId(); 123 | } 124 | 125 | /** 126 | * Metrics 아이디를 중복으로 설정하려고 할 경우 덮어쓰기 확인 127 | */ 128 | @Test 129 | @Tag("Overwrite") 130 | void testPutMetricsDuplicateId() { 131 | test.testPutMetricsDuplicateId(); 132 | testV2.testPutMetricsDuplicateId(); 133 | } 134 | 135 | /** 136 | * 접두어를 포함한 Metrics 설정이 올바르게 적용되는지 확인 137 | */ 138 | @Test 139 | @Tag("Filtering") 140 | void testMetricsPrefix() { 141 | test.testMetricsPrefix(); 142 | testV2.testMetricsPrefix(); 143 | } 144 | 145 | /** 146 | * Metrics 설정에 태그를 적용할 수 있는지 확인 147 | */ 148 | @Test 149 | @Tag("Filtering") 150 | void testMetricsTag() { 151 | test.testMetricsTag(); 152 | testV2.testMetricsTag(); 153 | } 154 | 155 | /** 156 | * Metrics 설정에 필터를 적용할 수 있는지 확인 157 | */ 158 | @Test 159 | @Tag("Filtering") 160 | void testMetricsFilter() { 161 | test.testMetricsFilter(); 162 | testV2.testMetricsFilter(); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /dotnet/Test/Accelerate.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | using Amazon.S3; 12 | using Amazon.S3.Model; 13 | using System; 14 | using System.Net; 15 | using Xunit; 16 | 17 | namespace s3tests 18 | { 19 | public class Accelerate : TestBase 20 | { 21 | public Accelerate(Xunit.Abstractions.ITestOutputHelper Output) => this.Output = Output; 22 | 23 | 24 | [Fact] 25 | [Trait(MainData.Major, "Accelerate")] 26 | [Trait(MainData.Minor, "Get")] 27 | [Trait(MainData.Explanation, "버킷의 Accelerate 설정 확인")] 28 | [Trait(MainData.Result, MainData.ResultSuccess)] 29 | public void TestGetBucketAccelerate() 30 | { 31 | var client = GetClient(); 32 | var bucketName = GetNewBucket(client); 33 | 34 | var response = client.GetBucketAccelerateConfiguration(bucketName); 35 | Assert.Equal(BucketAccelerateStatus.Suspended, response.Status); 36 | } 37 | 38 | [Fact] 39 | [Trait(MainData.Major, "Accelerate")] 40 | [Trait(MainData.Minor, "Put")] 41 | [Trait(MainData.Explanation, "버킷의 Accelerate 설정 확인")] 42 | [Trait(MainData.Result, MainData.ResultSuccess)] 43 | public void TestPutBucketAccelerate() 44 | { 45 | var client = GetClient(); 46 | var bucketName = GetNewBucket(client); 47 | 48 | client.PutBucketAccelerateConfiguration(bucketName, BucketAccelerateStatus.Enabled); 49 | 50 | var response = client.GetBucketAccelerateConfiguration(bucketName); 51 | Assert.Equal(BucketAccelerateStatus.Enabled, response.Status); 52 | } 53 | 54 | [Fact] 55 | [Trait(MainData.Major, "Accelerate")] 56 | [Trait(MainData.Minor, "Change")] 57 | [Trait(MainData.Explanation, "버킷의 Accelerate 설정 변경 확인")] 58 | [Trait(MainData.Result, MainData.ResultSuccess)] 59 | public void TestChangeBucketAccelerate() 60 | { 61 | var client = GetClient(); 62 | var bucketName = GetNewBucket(client); 63 | 64 | client.PutBucketAccelerateConfiguration(bucketName, BucketAccelerateStatus.Enabled); 65 | 66 | var response = client.GetBucketAccelerateConfiguration(bucketName); 67 | Assert.Equal(BucketAccelerateStatus.Enabled, response.Status); 68 | 69 | client.PutBucketAccelerateConfiguration(bucketName, BucketAccelerateStatus.Suspended); 70 | 71 | response = client.GetBucketAccelerateConfiguration(bucketName); 72 | Assert.Equal(BucketAccelerateStatus.Suspended, response.Status); 73 | } 74 | 75 | [Fact] 76 | [Trait(MainData.Major, "Accelerate")] 77 | [Trait(MainData.Minor, "Error")] 78 | [Trait(MainData.Explanation, "잘못된 Accelerate 설정시 실패 확인")] 79 | [Trait(MainData.Result, MainData.ResultFailure)] 80 | public void TestPutBucketAccelerateInvalid() 81 | { 82 | var client = GetClient(); 83 | var bucketName = GetNewBucket(client); 84 | 85 | var request = new PutBucketAccelerateConfigurationRequest 86 | { 87 | BucketName = bucketName, 88 | AccelerateConfiguration = new AccelerateConfiguration 89 | { 90 | Status = "Invalid" 91 | } 92 | }; 93 | 94 | var e = Assert.Throws(() => client.PutBucketAccelerateConfiguration(request)); 95 | Assert.Equal(HttpStatusCode.BadRequest, GetStatus(e)); 96 | Assert.Equal("MalformedXML", GetErrorCode(e)); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/main/Main.java: -------------------------------------------------------------------------------- 1 | package com.pspace.main; 2 | 3 | import org.apache.commons.cli.DefaultParser; 4 | import org.apache.commons.cli.HelpFormatter; 5 | import org.apache.commons.cli.Options; 6 | import org.apache.commons.cli.ParseException; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import com.pspace.jenkins.DBManager; 12 | import com.pspace.jenkins.PlatformInfo; 13 | import com.pspace.jenkins.XmlParser; 14 | 15 | import java.io.File; 16 | 17 | public class Main { 18 | private static final Logger log = LoggerFactory.getLogger(Main.class); 19 | 20 | public static void main(String[] args) { 21 | Options options = new Options(); 22 | 23 | options.addOption("h", "help", false, "Program Usage Manual"); 24 | options.addOption("f", "file", true, "*.xml file name"); 25 | options.addOption("b", "build", true, "Input Build Number"); 26 | options.addOption("c", "config", true, "Config file"); 27 | options.addOption("t", "table", true, "Table name"); 28 | 29 | // 플랫폼 관련 옵션 추가 30 | options.addOption("p", "platform", true, "Platform type (ifs3.0b, ifs3.0, ifs3.2, ksan)"); 31 | options.addOption("o", "os", true, "OS type (el7, r8)"); 32 | options.addOption("g", "gateway", true, "Gateway type (s3gw, proxy, -)"); 33 | options.addOption("e", "env", true, "Environment type. nohap, hap"); 34 | options.addOption("r", "trigger", true, "Trigger type (auto, manual)"); 35 | 36 | var parser = new DefaultParser(); 37 | var formatter = new HelpFormatter(); 38 | 39 | try { 40 | MainConfig config; 41 | 42 | var cmd = parser.parse(options, args); 43 | if (cmd.hasOption("h")) { 44 | help(formatter, options); 45 | return; 46 | } 47 | 48 | if (cmd.hasOption("c")) { 49 | config = MainConfig.load(cmd.getOptionValue("c")); 50 | } else { 51 | config = MainConfig.load("config.yml"); 52 | } 53 | 54 | String fileName = cmd.getOptionValue("f"); 55 | String tableName = cmd.getOptionValue("t"); 56 | int buildNumber = 0; 57 | 58 | if (cmd.hasOption("b")) { 59 | buildNumber = Integer.parseInt(cmd.getOptionValue("b")); 60 | } 61 | 62 | // 필수 파라미터 검증 63 | if (fileName == null || fileName.isEmpty()) { 64 | log.error("FileName is empty!"); 65 | return; 66 | } 67 | 68 | // 플랫폼 정보 검증 69 | String platform = cmd.getOptionValue("p"); 70 | String os = cmd.getOptionValue("o"); 71 | String gateway = cmd.getOptionValue("g"); 72 | String envType = cmd.getOptionValue("e"); 73 | String triggerType = cmd.getOptionValue("r"); 74 | 75 | if (StringUtils.isAnyBlank(platform, os, gateway, envType, triggerType)) { 76 | log.error("Platform information is incomplete! Required: platform, os, gateway, env, trigger"); 77 | help(formatter, options); 78 | return; 79 | } 80 | 81 | var file = new File(fileName); 82 | if (!file.exists()) { 83 | log.error("Error: File does not exist!"); 84 | return; 85 | } 86 | 87 | var xmlParser = new XmlParser(fileName); 88 | if (!xmlParser.read()) { 89 | log.error("Failed to parse XML file!"); 90 | return; 91 | } 92 | 93 | var platformInfo = new PlatformInfo(platform, os, gateway, envType, triggerType); 94 | var db = new DBManager(config.getDb(), buildNumber, xmlParser.getTestSuite(), tableName, platformInfo); 95 | if (!db.insert()) { 96 | log.error("Failed to insert data into database!"); 97 | return; 98 | } 99 | 100 | log.info("Successfully processed test results"); 101 | 102 | } catch (ParseException e) { 103 | log.error("Failed to parse command line arguments", e); 104 | help(formatter, options); 105 | } catch (Exception e) { 106 | log.error("Unexpected error occurred", e); 107 | } 108 | } 109 | 110 | private static void help(HelpFormatter formatter, Options options) { 111 | formatter.printHelp("xml-report-parser", options); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /java/src/test/java/org/example/s3tests/CSE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.s3tests; 12 | 13 | import org.junit.jupiter.api.AfterEach; 14 | import org.junit.jupiter.api.TestInfo; 15 | import org.junit.jupiter.api.Tag; 16 | import org.junit.jupiter.api.Test; 17 | 18 | /** 19 | * CSE(Client-Side Encryption) 테스트 20 | */ 21 | class CSE { 22 | 23 | org.example.test.CSE test = new org.example.test.CSE(); 24 | org.example.testV2.CSE testV2 = new org.example.testV2.CSE(); 25 | 26 | /** 27 | * 테스트 정리 작업 수행 28 | */ 29 | @AfterEach 30 | void clear(TestInfo testInfo) { 31 | test.clear(testInfo); 32 | testV2.clear(testInfo); 33 | } 34 | 35 | /** 36 | * [AES256] 1Byte 오브젝트를 암호화 하여 업로드한뒤, 다운로드하여 복호화 했을 경우 일치하는지 확인 37 | */ 38 | @Test 39 | @Tag("PutGet") 40 | void testCseEncryptedTransfer1b() { 41 | test.testCseEncryptedTransfer1b(); 42 | testV2.testCseEncryptedTransfer1b(); 43 | } 44 | 45 | /** 46 | * [AES256] 1KB 오브젝트를 암호화 하여 업로드한뒤, 다운로드하여 복호화 했을 경우 일치하는지 확인 47 | */ 48 | @Test 49 | @Tag("PutGet") 50 | void testCseEncryptedTransfer1kb() { 51 | test.testCseEncryptedTransfer1kb(); 52 | testV2.testCseEncryptedTransfer1kb(); 53 | } 54 | 55 | /** 56 | * [AES256] 1MB 오브젝트를 암호화 하여 업로드한뒤, 다운로드하여 복호화 했을 경우 일치하는지 확인 57 | */ 58 | @Test 59 | @Tag("PutGet") 60 | void testCseEncryptedTransfer1MB() { 61 | test.testCseEncryptedTransfer1MB(); 62 | testV2.testCseEncryptedTransfer1MB(); 63 | } 64 | 65 | /** 66 | * [AES256] 13Byte 오브젝트를 암호화 하여 업로드한뒤, 다운로드하여 복호화 했을 경우 일치하는지 확인 67 | */ 68 | @Test 69 | @Tag("PutGet") 70 | void testCseEncryptedTransfer13b() { 71 | test.testCseEncryptedTransfer13b(); 72 | testV2.testCseEncryptedTransfer13b(); 73 | } 74 | 75 | /** 76 | * [AES256] 암호화하고 메타데이터에 키값을 추가하여 업로드한 오브젝트가 올바르게 반영되었는지 확인 77 | */ 78 | @Test 79 | @Tag("Metadata") 80 | void testCseEncryptionMethodHead() { 81 | test.testCseEncryptionMethodHead(); 82 | testV2.testCseEncryptionMethodHead(); 83 | } 84 | 85 | /** 86 | * [AES256] 암호화 하여 업로드한 오브젝트를 다운로드하여 비교할경우 불일치 87 | */ 88 | @Test 89 | @Tag("ERROR") 90 | void testCseEncryptionNonDecryption() { 91 | test.testCseEncryptionNonDecryption(); 92 | testV2.testCseEncryptionNonDecryption(); 93 | } 94 | 95 | /** 96 | * [AES256] 암호화 없이 업로드한 오브젝트를 다운로드하여 복호화할 경우 실패 확인 97 | */ 98 | @Test 99 | @Tag("ERROR") 100 | void testCseNonEncryptionDecryption() { 101 | test.testCseNonEncryptionDecryption(); 102 | testV2.testCseNonEncryptionDecryption(); 103 | } 104 | 105 | /** 106 | * [AES256] 암호화 하여 업로드한 오브젝트에 대해 범위를 지정하여 읽기 성공 107 | */ 108 | @Test 109 | @Tag("RangeRead") 110 | void testCseEncryptionRangeRead() { 111 | test.testCseEncryptionRangeRead(); 112 | testV2.testCseEncryptionRangeRead(); 113 | } 114 | 115 | /** 116 | * [AES256] 암호화된 오브젝트 멀티파트 업로드 / 다운로드 성공 확인 117 | */ 118 | @Test 119 | @Tag("Multipart") 120 | void testCseEncryptionMultipartUpload() { 121 | test.testCseEncryptionMultipartUpload(); 122 | testV2.testCseEncryptionMultipartUpload(); 123 | } 124 | 125 | /** 126 | * CSE설정한 오브젝트를 여러번 반복하여 다운로드 성공 확인 127 | */ 128 | @Test 129 | @Tag("Get") 130 | void testCseGetObjectMany() { 131 | test.testCseGetObjectMany(); 132 | testV2.testCseGetObjectMany(); 133 | } 134 | 135 | /** 136 | * CSE설정한 오브젝트를 여러번 반복하여 Range 다운로드 성공 확인 137 | */ 138 | @Test 139 | @Tag("Get") 140 | void testCseRangeObjectMany() { 141 | test.testCseRangeObjectMany(); 142 | testV2.testCseRangeObjectMany(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /java/src/main/java/org/example/test/Accelerate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | package org.example.test; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertThrows; 15 | 16 | import org.apache.hc.core5.http.HttpStatus; 17 | import org.example.Data.MainData; 18 | import org.junit.jupiter.api.Tag; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import com.amazonaws.AmazonServiceException; 22 | import com.amazonaws.services.s3.model.BucketAccelerateConfiguration; 23 | import com.amazonaws.services.s3.model.BucketAccelerateStatus; 24 | import com.amazonaws.services.s3.model.SetBucketAccelerateConfigurationRequest; 25 | import org.junit.jupiter.api.parallel.Execution; 26 | import org.junit.jupiter.api.parallel.ExecutionMode; 27 | 28 | @Execution(ExecutionMode.CONCURRENT) 29 | public class Accelerate extends TestBase { 30 | @org.junit.jupiter.api.BeforeAll 31 | public static void beforeAll() { 32 | System.out.println("Accelerate Start"); 33 | } 34 | 35 | @org.junit.jupiter.api.AfterAll 36 | public static void afterAll() { 37 | System.out.println("Accelerate End"); 38 | } 39 | 40 | @Test 41 | @Tag("Put") 42 | public void testPutBucketAccelerate() { 43 | var client = getClient(); 44 | var bucketName = createBucket(client); 45 | 46 | client.setBucketAccelerateConfiguration(new SetBucketAccelerateConfigurationRequest(bucketName, null) 47 | .withAccelerateConfiguration(new BucketAccelerateConfiguration(BucketAccelerateStatus.Enabled))); 48 | } 49 | 50 | @Test 51 | @Tag("Get") 52 | public void testGetBucketAccelerate() { 53 | var client = getClient(); 54 | var bucketName = createBucket(client); 55 | 56 | client.setBucketAccelerateConfiguration(new SetBucketAccelerateConfigurationRequest(bucketName, null) 57 | .withAccelerateConfiguration(new BucketAccelerateConfiguration(BucketAccelerateStatus.Enabled))); 58 | 59 | var response = client.getBucketAccelerateConfiguration(bucketName); 60 | assertEquals(BucketAccelerateStatus.Enabled, response.getStatus()); 61 | } 62 | 63 | @Test 64 | @Tag("Change") 65 | public void testChangeBucketAccelerate() { 66 | var client = getClient(); 67 | var bucketName = createBucket(client); 68 | 69 | client.setBucketAccelerateConfiguration(new SetBucketAccelerateConfigurationRequest(bucketName, null) 70 | .withAccelerateConfiguration(new BucketAccelerateConfiguration(BucketAccelerateStatus.Enabled))); 71 | 72 | var response = client.getBucketAccelerateConfiguration(bucketName); 73 | assertEquals(BucketAccelerateStatus.Enabled, response.getStatus()); 74 | 75 | client.setBucketAccelerateConfiguration(new SetBucketAccelerateConfigurationRequest(bucketName, null) 76 | .withAccelerateConfiguration(new BucketAccelerateConfiguration(BucketAccelerateStatus.Suspended))); 77 | 78 | response = client.getBucketAccelerateConfiguration(bucketName); 79 | assertEquals(BucketAccelerateStatus.Suspended, response.getStatus()); 80 | } 81 | 82 | @Test 83 | @Tag("Error") 84 | public void testPutBucketAccelerateInvalid() { 85 | var client = getClient(); 86 | var bucketName = createBucket(client); 87 | 88 | var e = assertThrows(AmazonServiceException.class, 89 | () -> client 90 | .setBucketAccelerateConfiguration(new SetBucketAccelerateConfigurationRequest(bucketName, null) 91 | .withAccelerateConfiguration(new BucketAccelerateConfiguration("Invalid")))); 92 | assertEquals(HttpStatus.SC_BAD_REQUEST, e.getStatusCode()); 93 | assertEquals(MainData.MALFORMED_XML, e.getErrorCode()); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /dotnet/Data/MainData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 PSPACE, inc. KSAN Development Team ksan@pspace.co.kr 3 | * KSAN is a suite of free software: you can redistribute it and/or modify it under the terms of 4 | * the GNU General Public License as published by the Free Software Foundation, either version 5 | * 3 of the License. See LICENSE for details 6 | * 7 | * 본 프로그램 및 관련 소스코드, 문서 등 모든 자료는 있는 그대로 제공이 됩니다. 8 | * KSAN 프로젝트의 개발자 및 개발사는 이 프로그램을 사용한 결과에 따른 어떠한 책임도 지지 않습니다. 9 | * KSAN 개발팀은 사전 공지, 허락, 동의 없이 KSAN 개발에 관련된 모든 결과물에 대한 LICENSE 방식을 변경 할 권리가 있습니다. 10 | */ 11 | namespace s3tests 12 | { 13 | static public class MainData 14 | { 15 | public const string Major = "Major"; 16 | public const string Minor = "Minor"; 17 | public const string Explanation = "Explanation"; 18 | 19 | public const string Result = "Result"; 20 | public const string ResultSuccess = "Success"; 21 | public const string ResultFailure = "Failure"; 22 | 23 | 24 | public const string Different = "Different"; 25 | 26 | public const string True = "True"; 27 | public const string False = "False"; 28 | 29 | public const string S3TESTS_INI = "S3TESTS_INI"; 30 | 31 | public const int KB = 1024; 32 | public const int MB = 1024 * 1024; 33 | 34 | public const string HTTP = "http://"; 35 | public const string HTTPS = "https://"; 36 | 37 | public const string PolicyVersion = "Version"; 38 | public const string PolicyVersionDate = "2012-10-17"; 39 | public const string PolicyEffect = "Effect"; 40 | public const string PolicyPrincipal = "Principal"; 41 | public const string PolicyNotPrincipal = "NotPrincipal"; 42 | public const string PolicyAction = "Action"; 43 | public const string PolicyResource = "Resource"; 44 | public const string PolicyEffectAllow = "Allow"; 45 | public const string PolicyEffectDeny = "Deny"; 46 | public const string PolicyStatement = "Statement"; 47 | public const string PolicyCondition = "Condition"; 48 | public const string PolicyResourcePrefix = "arn:aws:s3:::"; 49 | 50 | #region ErrorCode 51 | public const string INVALID_ARGUMENT = "InvalidArgument"; 52 | public const string INVALID_BUCKET_NAME = "InvalidBucketName"; 53 | public const string INVALID_ACCESS_KEY_ID = "InvalidAccessKeyId"; 54 | public const string BAD_REQUEST = "BadRequest"; 55 | public const string NO_SUCH_BUCKET = "NoSuchBucket"; 56 | public const string BUCKET_NOT_EMPTY = "BucketNotEmpty"; 57 | public const string NO_SUCH_KEY = "NoSuchKey"; 58 | public const string ACCESS_DENIED = "AccessDenied"; 59 | public const string PRECONDITION_FAILED = "PreconditionFailed"; 60 | public const string NOT_MODIFIED = "NotModified"; 61 | public const string BUCKET_ALREADY_OWNED_BY_YOU = "BucketAlreadyOwnedByYou"; 62 | public const string BUCKET_ALREADY_EXISTS = "BucketAlreadyExists"; 63 | public const string UNRESOLVABLE_GRANT_BY_EMAIL_ADDRESS = "UnresolvableGrantByEmailAddress"; 64 | public const string INVALID_REQUEST = "InvalidRequest"; 65 | public const string MALFORMED_XML = "MalformedXML"; 66 | public const string INVALID_RANGE = "InvalidRange"; 67 | public const string ENTITY_TOO_SMALL = "EntityTooSmall"; 68 | public const string NO_SUCH_UPLOAD = "NoSuchUpload"; 69 | public const string INVALID_PART = "InvalidPart"; 70 | public const string INVALID_TAG = "InvalidTag"; 71 | public const string INVALID_BUCKET_STATE = "InvalidBucketState"; 72 | public const string INVALID_RETENTION_PERIOD = "InvalidRetentionPeriod"; 73 | public const string OBJECT_LOCK_CONFIGURATION_NOT_FOUND_ERROR = "ObjectLockConfigurationNotFoundError"; 74 | public const string NOT_IMPLEMENTED = "NotImplemented"; 75 | public const string SIGNATURE_DOES_NOT_MATCH = "SignatureDoesNotMatch"; 76 | public const string PERMANENT_REDIRECT = "PermanentRedirect"; 77 | public const string NO_SUCH_PUBLIC_ACCESS_BLOCK_CONFIGURATION = "NoSuchPublicAccessBlockConfiguration"; 78 | public const string AUTHORIZATION_QUERY_PARAMETERS_ERROR = "AuthorizationQueryParametersError"; 79 | public const string INVALID_TARGET_BUCKET_FOR_LOGGING = "InvalidTargetBucketForLogging"; 80 | public const string NO_SUCH_CONFIGURATION = "NoSuchConfiguration"; 81 | public const string INVALID_CONFIGURATION_ID = "InvalidConfigurationId"; 82 | #endregion 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Utils/xmlParser/src/com/pspace/jenkins/DBManager.java: -------------------------------------------------------------------------------- 1 | package com.pspace.jenkins; 2 | 3 | import java.sql.*; 4 | 5 | public class DBManager { 6 | final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DBManager.class); 7 | 8 | private final int buildNumber; 9 | private final TestSuite testSuite; 10 | private final String tableName; 11 | private final DbConfig dbConfig; 12 | private final PlatformInfo platformInfo; 13 | 14 | public DBManager(DbConfig dbConfig, int buildNumber, TestSuite testSuite, String tableName, 15 | PlatformInfo platformInfo) { 16 | this.buildNumber = buildNumber; 17 | this.testSuite = testSuite; 18 | this.dbConfig = dbConfig; 19 | this.tableName = tableName; 20 | this.platformInfo = platformInfo; 21 | } 22 | 23 | private boolean createDetailTable(Connection connection) throws SQLException { 24 | var createTableQuery = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (" 25 | + "id int(11) NOT NULL AUTO_INCREMENT," 26 | + "build_id int(11) NOT NULL," 27 | + "class_name varchar(256) NOT NULL," 28 | + "case_name varchar(256) NOT NULL," 29 | + "result varchar(20) NOT NULL," 30 | + "error_type text DEFAULT NULL," 31 | + "message longtext DEFAULT NULL," 32 | + "content longtext DEFAULT NULL," 33 | + "system_out longtext DEFAULT NULL," 34 | + "system_err longtext DEFAULT NULL," 35 | + "times float NOT NULL," 36 | + "PRIMARY KEY (id)" 37 | + ")"; 38 | 39 | try (var stmt = connection.createStatement()) { 40 | stmt.execute(createTableQuery); 41 | return true; 42 | } 43 | } 44 | 45 | public boolean insert() { 46 | try (var connection = DriverManager.getConnection( 47 | dbConfig.getConnectionUrl(), 48 | dbConfig.getUser(), 49 | dbConfig.getPassword())) { 50 | 51 | // Create detail table if not exists 52 | if (!createDetailTable(connection)) { 53 | log.error("Failed to create detail table"); 54 | return false; 55 | } 56 | 57 | // Insert test summary 58 | var summaryQuery = "INSERT INTO s3_summary (build_id, platform, os, gateway, env_type, language, sdk_version, tests, passed, failure, error, skipped, times, file_name) " 59 | + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 60 | 61 | try (var stmt = connection.prepareStatement(summaryQuery)) { 62 | stmt.setInt(1, buildNumber); 63 | stmt.setString(2, platformInfo.getPlatform()); 64 | stmt.setString(3, platformInfo.getOs()); 65 | stmt.setString(4, platformInfo.getGateway()); 66 | stmt.setString(5, platformInfo.getEnvType()); 67 | stmt.setString(6, testSuite.getLanguage()); 68 | stmt.setString(7, testSuite.getSdkVersion()); 69 | stmt.setInt(8, testSuite.getTests()); 70 | stmt.setInt(9, testSuite.getPassed()); 71 | stmt.setInt(10, testSuite.getFailures()); 72 | stmt.setInt(11, testSuite.getErrors()); 73 | stmt.setInt(12, testSuite.getSkipped()); 74 | stmt.setFloat(13, testSuite.getTimeAsFloat()); 75 | stmt.setString(14, testSuite.getResultFileName()); 76 | stmt.executeUpdate(); 77 | } 78 | 79 | // Insert test details 80 | var detailQuery = "INSERT INTO `" + tableName 81 | + "` (build_id, class_name, case_name, result, error_type, message, content, system_out, system_err, times)" 82 | + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 83 | 84 | try (var stmt = connection.prepareStatement(detailQuery)) { 85 | // Set loop-invariant values 86 | stmt.setInt(1, buildNumber); 87 | 88 | for (var testCase : testSuite.getTestCases()) { 89 | stmt.setString(2, testCase.getClassname()); 90 | stmt.setString(3, testCase.getName()); 91 | stmt.setString(4, testCase.getResult()); 92 | stmt.setString(5, testCase.getErrorType()); 93 | stmt.setString(6, testCase.getErrorMessage()); 94 | stmt.setString(7, testCase.getErrorContent()); 95 | stmt.setString(8, testCase.getSystemOut()); 96 | stmt.setString(9, testCase.getSystemErr()); 97 | stmt.setFloat(10, testCase.getTimeAsFloat()); 98 | stmt.addBatch(); 99 | } 100 | stmt.executeBatch(); 101 | } 102 | 103 | return true; 104 | } catch (SQLException e) { 105 | log.error("Database error", e); 106 | return false; 107 | } 108 | } 109 | } --------------------------------------------------------------------------------