Skip to content

Commit

Permalink
Sonar test coverage and bug fixing
Browse files Browse the repository at this point in the history
  • Loading branch information
Lerch, Kay committed Sep 11, 2016
1 parent aaff3da commit 0cd1bf4
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 21 deletions.
50 changes: 49 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<junit.version>4.12</junit.version>
<mockito.version>1.10.19</mockito.version>
<alexa-skillskit-version>1.1.3</alexa-skillskit-version>
<sonar.junit.reportsPath>${project.basedir}/target/surefire-reports</sonar.junit.reportsPath>
<sonar.jacoco.itReportPath>${project.basedir}/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.language>java</sonar.language>
<sonar.jacoco.reportPath>target/jacoco.exec</sonar.jacoco.reportPath>
</properties>

<build>
Expand All @@ -69,6 +73,19 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.failsafe.version}</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>org.sonar.java.jacoco.JUnitListener</value>
</property>
</properties>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
</plugin>
</plugins>
</pluginManagement>
Expand Down Expand Up @@ -113,9 +130,34 @@
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<goal>verify</goal>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent-for-ut</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>agent-for-it</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down Expand Up @@ -204,6 +246,12 @@
<scope>test</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.sonarsource.java</groupId>
<artifactId>sonar-jacoco-listeners</artifactId>
<version>3.8</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public class AWSDynamoStateHandler extends AlexaSessionStateHandler {
private final String tableName;
private final long readCapacityUnits;
private final long writeCapacityUnits;
private final String tablePrefix = "alexa-";
private final String attributeValueApp = "__application";
private final String pkModel = "model-class";
private final String pkUser = "amzn-user-id";
private final String attributeKeyState = "state";
private static final String tablePrefix = "alexa-";
private static final String attributeValueApp = "__application";
private static final String pkModel = "model-class";
private static final String pkUser = "amzn-user-id";
private static final String attributeKeyState = "state";
private Boolean tableExistenceApproved = false;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ public class AWSIotStateHandler extends AlexaSessionStateHandler {

private final AWSIot awsClient;
private final AWSIotData awsDataClient;
private final String thingAttributeName = "name";
private final String thingAttributeUser = "amzn-user-id";
private final String thingAttributeApp = "amzn-app-id";
private static final String thingAttributeName = "name";
private static final String thingAttributeUser = "amzn-user-id";
private static final String thingAttributeApp = "amzn-app-id";
private List<String> thingsExisting = new ArrayList<>();

public AWSIotStateHandler(final Session session) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public class AWSS3StateHandler extends AlexaSessionStateHandler {

private final AmazonS3 awsClient;
private final String bucketName;
private final String folderNameApp = "__application";
private final String fileExtension = "json";
private static final String folderNameApp = "__application";
private static final String fileExtension = "json";

/**
* Takes the Alexa session. An AWS client for accessing the S3 bucket will make use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import io.klerch.alexa.state.utils.AlexaStateException;
import org.apache.log4j.Logger;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Optional;

Expand Down
13 changes: 10 additions & 3 deletions src/main/java/io/klerch/alexa/state/utils/ConversionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,34 @@

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.Validate;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* Some utils to convert data structures
*/
public class ConversionUtils {
private static final Logger log = Logger.getLogger(ConversionUtils.class);

/**
* A json-string of key-value pairs is read out as a map
* @param json json-string of key-value pairs
* @return a map with corresponding key-value paris
*/
public static Map<String, Object> mapJson(final String json) {
final ObjectMapper mapper = new ObjectMapper();
if (json == null || json.isEmpty()) new HashMap<>();
if (json == null || json.isEmpty()) {
return new HashMap<>();
}
final TypeReference<HashMap<String,Object>> typeRef = new TypeReference<HashMap<String,Object>>() {};
try {
// read jsonString into map
return mapper.readValue(json, typeRef);
} catch (IOException e) {
e.printStackTrace();
log.error(e);
return new HashMap<>();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
package io.klerch.alexa.state.handler;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.*;
import io.klerch.alexa.state.model.dummies.Model;
import org.junit.Test;
import org.mockito.Mockito;
Expand All @@ -17,15 +16,17 @@
import java.util.Map;

import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;

public class AWSDynamoStateHandlerTest extends AlexaStateHandlerTest<AWSDynamoStateHandler> {
private final String tableName = "tableName";

@Override
public AWSDynamoStateHandler getHandler() {
final AmazonDynamoDBClient awsClient = mock(AmazonDynamoDBClient.class);
handler = new AWSDynamoStateHandler(session, awsClient, tableName);
handler = new AWSDynamoStateHandler(session, awsClient);

final String tableName = handler.getTableName();

// prepare static read return from DynamoDB without given model-Id
final String jsonApp = "{\"id\":null,\"sampleApplication\":true}";
Expand Down Expand Up @@ -59,10 +60,27 @@ public AWSDynamoStateHandler getHandler() {
final GetItemResult resultUserId = new GetItemResult().withItem(mapUserId);
final GetItemResult resultAppId = new GetItemResult().withItem(mapAppId);

// mock get items for model with id
Mockito.when(awsClient.getItem(tableName, handler.getUserScopedKeyAttributes(Model.class, modelId)))
.thenReturn(resultUserId);
Mockito.when(awsClient.getItem(tableName, handler.getAppScopedKeyAttributes(Model.class, modelId)))
.thenReturn(resultAppId);

// mock get items for absent model (with empty response)
Mockito.when(awsClient.getItem(tableName, handler.getUserScopedKeyAttributes(Model.class, absentModelId)))
.thenReturn(new GetItemResult());
Mockito.when(awsClient.getItem(tableName, handler.getAppScopedKeyAttributes(Model.class, absentModelId)))
.thenReturn(new GetItemResult());

// on create table call always return table in ACTIVE state
final TableDescription tableDescription = new TableDescription().withTableName(tableName).withTableStatus(TableStatus.ACTIVE);
final CreateTableResult createResult = new CreateTableResult().withTableDescription(tableDescription);
Mockito.when(awsClient.createTable(any(CreateTableRequest.class))).thenReturn(createResult);

// mock describe table request to always return a table whose name is
final DescribeTableResult describeResult = new DescribeTableResult().withTable(tableDescription);
Mockito.when(awsClient.describeTable(any(DescribeTableRequest.class))).thenReturn(describeResult);

return handler;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (invocationOnMock.getMethod().getName().equals("getThingShadow")) {
// build shadow JSON with reported state for Model with one
// instance having an id and another having no id
final AWSIotStateHandler handler = new AWSIotStateHandler(session);
final String keyWithId = AlexaStateModel.getAttributeKey(Model.class, modelId);
final String keyWithoutId = AlexaStateModel.getAttributeKey(Model.class, null);
final String jsonWithId = "\"" + keyWithId + "\":{\"id\":\"" + modelId + "\",\"sampleApplication\":true,\"sampleUser\":\"sampleUser\"}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public AWSS3StateHandler getHandler() {
final AmazonS3Client s3Client = Mockito.mock(AmazonS3Client.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
if (invocationOnMock.getMethod().getName().equals("doesObjectExist")) return true;
if (invocationOnMock.getMethod().getName().equals("doesObjectExist")) {
// true in case of any model requested beside the one assumed as absent
return !(Arrays.stream(invocationOnMock.getArguments()).filter(p -> p.toString().contains(absentModelId)).findAny().isPresent());
}
if (invocationOnMock.getMethod().getName().equals("putObject")) return new PutObjectResult();
if (invocationOnMock.getMethod().getName().equals("deleteObject")) return null;
if (invocationOnMock.getMethod().getName().equals("getObject")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.amazon.speech.speechlet.Session;
import com.amazon.speech.speechlet.User;
import io.klerch.alexa.state.model.dummies.Model;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

Expand All @@ -23,6 +24,7 @@ public abstract class AlexaStateHandlerTest<THandler extends AlexaStateHandler>
THandler handler;
Session session;
final String modelId = "modelId";
final String absentModelId = "nonexisting";

public abstract THandler getHandler();

Expand Down Expand Up @@ -95,6 +97,11 @@ public void crudModel() throws Exception {
assertFalse(session.getAttributes().containsKey(key));
}

@Test
public void readAbsentModel() throws Exception {
Assert.assertFalse(handler.readModel(Model.class, absentModelId).isPresent());
}

@Test
public void crudModelWithId() throws Exception {
session.getAttributes().clear();
Expand Down

0 comments on commit 0cd1bf4

Please sign in to comment.