Admin: Add tests for Java SDK (#6002)
This commit is contained in:
parent
c5a91e6cc6
commit
d525423f94
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@ -70,6 +70,35 @@ jobs:
|
||||
run:
|
||||
make lint
|
||||
|
||||
javatest:
|
||||
name: Test behaviour for Java SDK
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.8"
|
||||
- name: Start MotoServer
|
||||
run: |
|
||||
pip install build
|
||||
python -m build
|
||||
docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/scripts/ci_moto_server.sh &
|
||||
python scripts/ci_wait_for_server.py
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'maven'
|
||||
- name: Build with Maven
|
||||
run: |
|
||||
mkdir ~/.aws && touch ~/.aws/credentials && echo -e "[default]\naws_access_key_id = test\naws_secret_access_key = test" > ~/.aws/credentials
|
||||
cd other_langs/tests_java && mvn test
|
||||
|
||||
test:
|
||||
name: Unit test
|
||||
runs-on: ubuntu-latest
|
||||
@ -182,7 +211,7 @@ jobs:
|
||||
deploy:
|
||||
name: Deploy
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test, testserver ]
|
||||
needs: [javatest, test, testserver ]
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'getmoto/moto' }}
|
||||
strategy:
|
||||
matrix:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,3 +30,4 @@ htmlcov/
|
||||
docs/_build
|
||||
moto_recording
|
||||
.hypothesis
|
||||
other_langs/tests_java/target
|
||||
|
@ -71,10 +71,14 @@ class RESTError(HTTPException):
|
||||
self, *args: Any, **kwargs: Any # pylint: disable=unused-argument
|
||||
) -> List[Tuple[str, str]]:
|
||||
return [
|
||||
("X-Amzn-ErrorType", self.error_type or "UnknownError"),
|
||||
("X-Amzn-ErrorType", self.relative_error_type or "UnknownError"),
|
||||
("Content-Type", self.content_type),
|
||||
]
|
||||
|
||||
@property
|
||||
def relative_error_type(self) -> str:
|
||||
return self.error_type
|
||||
|
||||
def get_body(
|
||||
self, *args: Any, **kwargs: Any # pylint: disable=unused-argument
|
||||
) -> str:
|
||||
@ -95,6 +99,12 @@ class JsonRESTError(RESTError):
|
||||
)
|
||||
self.content_type = "application/json"
|
||||
|
||||
@property
|
||||
def relative_error_type(self) -> str:
|
||||
# https://smithy.io/2.0/aws/protocols/aws-json-1_1-protocol.html
|
||||
# If a # character is present, then take only the contents after the first # character in the value
|
||||
return self.error_type.split("#")[-1]
|
||||
|
||||
def get_body(self, *args: Any, **kwargs: Any) -> str:
|
||||
return self.description
|
||||
|
||||
|
@ -315,9 +315,9 @@ class TableAlreadyExistsException(JsonRESTError):
|
||||
|
||||
|
||||
class ResourceInUseException(JsonRESTError):
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, msg: Optional[str] = None) -> None:
|
||||
er = ERROR_TYPE_PREFIX + "ResourceInUseException"
|
||||
super().__init__(er, "Resource in use")
|
||||
super().__init__(er, msg or "Resource in use")
|
||||
|
||||
|
||||
class StreamAlreadyEnabledException(JsonRESTError):
|
||||
|
@ -60,7 +60,7 @@ class DynamoDBBackend(BaseBackend):
|
||||
|
||||
def create_table(self, name: str, **params: Any) -> Table:
|
||||
if name in self.tables:
|
||||
raise ResourceInUseException
|
||||
raise ResourceInUseException(f"Table already exists: {name}")
|
||||
table = Table(
|
||||
name, account_id=self.account_id, region=self.region_name, **params
|
||||
)
|
||||
|
112
other_langs/tests_java/pom.xml
Normal file
112
other_langs/tests_java/pom.xml
Normal file
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>moto.tests</groupId>
|
||||
<artifactId>java-tests</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<name>java-tests</name>
|
||||
<url>docs.getmoto.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>bom</artifactId>
|
||||
<version>2.20.14</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>dynamodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>netty-nio-client</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>apache-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>url-connection-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>apache-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||
<plugins>
|
||||
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.7.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,51 @@
|
||||
package moto.tests;
|
||||
|
||||
import software.amazon.awssdk.http.SdkHttpClient;
|
||||
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
|
||||
import software.amazon.awssdk.http.apache.ApacheHttpClient;
|
||||
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
|
||||
import software.amazon.awssdk.utils.AttributeMap;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* The module containing all dependencies required by the {@link Handler}.
|
||||
*/
|
||||
public class DependencyFactory {
|
||||
|
||||
private static final URI MOTO_URI = URI.create("http://localhost:5000");
|
||||
|
||||
private DependencyFactory() {}
|
||||
|
||||
/**
|
||||
* @return an instance of S3Client
|
||||
*/
|
||||
public static S3Client s3Client() {
|
||||
return S3Client.builder()
|
||||
.region(Region.US_EAST_1)
|
||||
.httpClientBuilder(ApacheHttpClient.builder())
|
||||
.endpointOverride(MOTO_URI)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static DynamoDbClient dynamoClient() {
|
||||
final AttributeMap attributeMap = AttributeMap.builder()
|
||||
.put(SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES, true)
|
||||
.build();
|
||||
// Not in use at the moment, but useful for testing
|
||||
SdkHttpClient proxy_client = UrlConnectionHttpClient.builder()
|
||||
.socketTimeout(Duration.ofMinutes(1))
|
||||
.proxyConfiguration(proxy -> proxy.endpoint(URI.create("http://localhost:8080")))
|
||||
.buildWithDefaults(attributeMap);
|
||||
return DynamoDbClient.builder()
|
||||
.region(Region.US_EAST_1)
|
||||
// .httpClient(client)
|
||||
.httpClientBuilder(ApacheHttpClient.builder())
|
||||
.endpointOverride(MOTO_URI)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package moto.tests;
|
||||
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
|
||||
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeyType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse;
|
||||
|
||||
public class DynamoLogic {
|
||||
|
||||
private final DynamoDbClient client;
|
||||
public DynamoLogic() {
|
||||
client = DependencyFactory.dynamoClient();
|
||||
}
|
||||
|
||||
public String createTable(String tableName, String key) {
|
||||
CreateTableRequest request = CreateTableRequest.builder()
|
||||
.attributeDefinitions(AttributeDefinition.builder()
|
||||
.attributeName(key)
|
||||
.attributeType(ScalarAttributeType.S)
|
||||
.build())
|
||||
.keySchema(KeySchemaElement.builder()
|
||||
.attributeName(key)
|
||||
.keyType(KeyType.HASH)
|
||||
.build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder()
|
||||
.readCapacityUnits(new Long(10))
|
||||
.writeCapacityUnits(new Long(10))
|
||||
.build())
|
||||
.tableName(tableName)
|
||||
.build();
|
||||
System.out.println("Prepared CreateTableRequest");
|
||||
|
||||
CreateTableResponse response = this.client.createTable(request);
|
||||
System.out.println(response.tableDescription());
|
||||
|
||||
return response.tableDescription().tableName();
|
||||
}
|
||||
}
|
83
other_langs/tests_java/src/main/java/moto/tests/Handler.java
Normal file
83
other_langs/tests_java/src/main/java/moto/tests/Handler.java
Normal file
@ -0,0 +1,83 @@
|
||||
package moto.tests;
|
||||
|
||||
import software.amazon.awssdk.core.sync.RequestBody;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.S3Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Example class as provided by AWS - verify that basic S3 functions work
|
||||
*/
|
||||
public class Handler {
|
||||
private final S3Client s3Client;
|
||||
|
||||
public Handler() {
|
||||
s3Client = DependencyFactory.s3Client();
|
||||
}
|
||||
|
||||
public void sendRequest() {
|
||||
String bucket = "bucket" + System.currentTimeMillis();
|
||||
String key = "key";
|
||||
|
||||
tutorialSetup(s3Client, bucket);
|
||||
|
||||
System.out.println("Uploading object...");
|
||||
|
||||
s3Client.putObject(PutObjectRequest.builder().bucket(bucket).key(key)
|
||||
.build(),
|
||||
RequestBody.fromString("Testing with the {sdk-java}"));
|
||||
|
||||
System.out.println("Upload complete");
|
||||
System.out.printf("%n");
|
||||
|
||||
cleanUp(s3Client, bucket, key);
|
||||
|
||||
System.out.println("Closing the connection to {S3}");
|
||||
s3Client.close();
|
||||
System.out.println("Connection closed");
|
||||
System.out.println("Exiting...");
|
||||
}
|
||||
|
||||
public static void tutorialSetup(S3Client s3Client, String bucketName) {
|
||||
try {
|
||||
s3Client.createBucket(CreateBucketRequest
|
||||
.builder()
|
||||
.bucket(bucketName)
|
||||
.build());
|
||||
System.out.println("Creating bucket: " + bucketName);
|
||||
s3Client.waiter().waitUntilBucketExists(HeadBucketRequest.builder()
|
||||
.bucket(bucketName)
|
||||
.build());
|
||||
System.out.println(bucketName + " is ready.");
|
||||
System.out.printf("%n");
|
||||
} catch (S3Exception e) {
|
||||
System.err.println(e.awsErrorDetails().errorMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void cleanUp(S3Client s3Client, String bucketName, String keyName) {
|
||||
System.out.println("Cleaning up...");
|
||||
try {
|
||||
System.out.println("Deleting object: " + keyName);
|
||||
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder().bucket(bucketName).key(keyName).build();
|
||||
s3Client.deleteObject(deleteObjectRequest);
|
||||
System.out.println(keyName + " has been deleted.");
|
||||
System.out.println("Deleting bucket: " + bucketName);
|
||||
DeleteBucketRequest deleteBucketRequest = DeleteBucketRequest.builder().bucket(bucketName).build();
|
||||
s3Client.deleteBucket(deleteBucketRequest);
|
||||
System.out.println(bucketName + " has been deleted.");
|
||||
System.out.printf("%n");
|
||||
} catch (S3Exception e) {
|
||||
System.err.println(e.awsErrorDetails().errorMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
System.out.println("Cleanup complete");
|
||||
System.out.printf("%n");
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package moto.tests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ResourceInUseException;
|
||||
|
||||
public class DynamoTest {
|
||||
|
||||
@Test
|
||||
public void testSingleTableExists() {
|
||||
DynamoLogic logic = new DynamoLogic();
|
||||
String table_name = logic.createTable("table", "key");
|
||||
|
||||
assertEquals("table", table_name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableCannotBeCreatedTwice() {
|
||||
DynamoLogic logic = new DynamoLogic();
|
||||
// Going once...
|
||||
logic.createTable("table2", "key");
|
||||
try {
|
||||
// Going twice should throw a specific exception
|
||||
logic.createTable("table2", "key");
|
||||
} catch (ResourceInUseException riue) {
|
||||
assertTrue(riue.getMessage().startsWith("Table already exists: table2"));
|
||||
}
|
||||
}
|
||||
}
|
16
other_langs/tests_java/src/test/java/moto/tests/S3Test.java
Normal file
16
other_langs/tests_java/src/test/java/moto/tests/S3Test.java
Normal file
@ -0,0 +1,16 @@
|
||||
package moto.tests;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class S3Test
|
||||
{
|
||||
|
||||
@Test
|
||||
public void connectToS3() {
|
||||
Handler handler = new Handler();
|
||||
handler.sendRequest();
|
||||
}
|
||||
}
|
@ -24,9 +24,7 @@ def test_table_list():
|
||||
res = test_client.post(
|
||||
"/", headers=headers, data=json.dumps({"TableName": "test-table2"})
|
||||
)
|
||||
res.headers.should.have.key("X-Amzn-ErrorType").equals(
|
||||
"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException"
|
||||
)
|
||||
res.headers.should.have.key("X-Amzn-ErrorType").equals("ResourceNotFoundException")
|
||||
body = json.loads(res.data.decode("utf-8"))
|
||||
body.should.equal(
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user