summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyan Campbell <ryanjcampbell@google.com>2017-09-07 10:42:36 -0700
committerRyan Campbell <ryanjcampbell@google.com>2017-09-19 13:32:36 -0700
commita9c0f414d5c2e77213e2e21739df96061e5f13cd (patch)
tree9bf15f80e7453b4b4d09abc0b0765122388ac00f /src
parente8513ec3e804d4affc3a670b81e7948fe635a98d (diff)
downloaddashboard-a9c0f414d5c2e77213e2e21739df96061e5f13cd.tar.gz
Create entity for test acknowledgements.
Define a database entity for storing information about test issue acknowledgements. Test: tests pass Bug: 65208372 Change-Id: I3e6a5265d8d443801ae00e9c0e210d19be46ac59
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java282
-rw-r--r--src/test/java/com/android/vts/entity/TestAcknowledgmentEntityTest.java170
2 files changed, 452 insertions, 0 deletions
diff --git a/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java b/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java
new file mode 100644
index 0000000..66b56b8
--- /dev/null
+++ b/src/main/java/com/android/vts/entity/TestAcknowledgmentEntity.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may
+ * obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.vts.entity;
+
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Text;
+import com.google.appengine.api.users.User;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Entity describing a test failure acknowledgment. */
+public class TestAcknowledgmentEntity implements DashboardEntity {
+ protected static final Logger logger =
+ Logger.getLogger(TestAcknowledgmentEntity.class.getName());
+
+ public static final String KIND = "TestAcknowledgment";
+ public static final String KEY = "key";
+ public static final String TEST_KEY = "testKey";
+ public static final String TEST_NAME = "testName";
+ public static final String USER = "user";
+ public static final String CREATED = "created";
+ public static final String BRANCHES = "branches";
+ public static final String DEVICES = "devices";
+ public static final String TEST_CASE_NAMES = "testCaseNames";
+ public static final String NOTE = "note";
+
+ private final Key key;
+ private final long created;
+ public final Key test;
+ public final User user;
+ public final Set<String> branches;
+ public final Set<String> devices;
+ public final Set<String> testCaseNames;
+ public final String note;
+
+ /**
+ * Create a AcknowledgmentEntity object.
+ *
+ * @param key The key of the AcknowledgmentEntity in the database.
+ * @param created The timestamp when the entity was created (in microseconds).
+ * @param test The key of the test.
+ * @param user The user who created or last modified the entity.
+ * @param branches The list of branch names for which the acknowledgment applies (or null if
+ * all).
+ * @param devices The list of device build flavors for which the acknowledgment applies (or
+ * null if all).
+ * @param testCaseNames The list of test case names known to fail (or null if all).
+ * @param note A text blob with details about the failure (or null if all).
+ */
+ private TestAcknowledgmentEntity(
+ Key key,
+ long created,
+ Key test,
+ User user,
+ List<String> branches,
+ List<String> devices,
+ List<String> testCaseNames,
+ Text note) {
+ this.test = test;
+ this.user = user;
+ if (branches != null) this.branches = new HashSet(branches);
+ else this.branches = new HashSet<>();
+
+ if (devices != null) this.devices = new HashSet(devices);
+ else this.devices = new HashSet<>();
+
+ if (testCaseNames != null) this.testCaseNames = new HashSet(testCaseNames);
+ else this.testCaseNames = new HashSet<>();
+
+ if (note != null) this.note = note.getValue();
+ else this.note = null;
+
+ this.key = key;
+ this.created = created;
+ }
+
+ /**
+ * Create a AcknowledgmentEntity object.
+ *
+ * @param test The key of the test.
+ * @param user The user who created or last modified the entity.
+ * @param branches The list of branch names for which the acknowledgment applies (or null if
+ * all).
+ * @param devices The list of device build flavors for which the acknowledgment applies (or
+ * null if all).
+ * @param testCaseNames The list of test case names known to fail (or null if all).
+ * @param note A text blob with details about the failure (or null if all).
+ */
+ public TestAcknowledgmentEntity(
+ Key test,
+ User user,
+ List<String> branches,
+ List<String> devices,
+ List<String> testCaseNames,
+ Text note) {
+ this(null, -1, test, user, branches, devices, testCaseNames, note);
+ }
+
+ @Override
+ public Entity toEntity() {
+ Entity ackEntity;
+ if (this.key == null) ackEntity = new Entity(KIND);
+ else ackEntity = new Entity(key);
+
+ ackEntity.setProperty(TEST_KEY, this.test);
+ ackEntity.setProperty(USER, this.user);
+
+ long created = this.created;
+ if (created < 0) created = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
+ ackEntity.setProperty(CREATED, created);
+
+ if (this.branches != null && this.branches.size() > 0)
+ ackEntity.setUnindexedProperty(BRANCHES, new ArrayList<>(this.branches));
+
+ if (this.devices != null && this.devices.size() > 0)
+ ackEntity.setUnindexedProperty(DEVICES, new ArrayList<>(this.devices));
+
+ if (this.testCaseNames != null && this.testCaseNames.size() > 0)
+ ackEntity.setUnindexedProperty(TEST_CASE_NAMES, new ArrayList<>(this.testCaseNames));
+
+ if (this.note != null) ackEntity.setUnindexedProperty(NOTE, new Text(this.note));
+ return ackEntity;
+ }
+
+ /**
+ * Convert an Entity object to a TestAcknowledgmentEntity.
+ *
+ * @param e The entity to process.
+ * @return TestEntity object with the properties from e processed, or null if incompatible.
+ */
+ @SuppressWarnings("unchecked")
+ public static TestAcknowledgmentEntity fromEntity(Entity e) {
+ if (!e.getKind().equals(KIND)
+ || !e.hasProperty(TEST_KEY)
+ || !e.hasProperty(USER)
+ || !e.hasProperty(CREATED)) {
+ logger.log(
+ Level.WARNING, "Missing attributes in acknowledgment entity: " + e.toString());
+ return null;
+ }
+ try {
+ Key test = (Key) e.getProperty(TEST_KEY);
+ User user = (User) e.getProperty(USER);
+ long created = (long) e.getProperty(CREATED);
+
+ List<String> branches;
+ if (e.hasProperty(BRANCHES)) branches = (List<String>) e.getProperty(BRANCHES);
+ else branches = null;
+
+ List<String> devices;
+ if (e.hasProperty(DEVICES)) devices = (List<String>) e.getProperty(DEVICES);
+ else devices = null;
+
+ List<String> testCaseNames;
+ if (e.hasProperty(TEST_CASE_NAMES))
+ testCaseNames = (List<String>) e.getProperty(TEST_CASE_NAMES);
+ else testCaseNames = null;
+
+ Text note = null;
+ if (e.hasProperty(NOTE)) note = (Text) e.getProperty(NOTE);
+ return new TestAcknowledgmentEntity(
+ e.getKey(), created, test, user, branches, devices, testCaseNames, note);
+ } catch (ClassCastException exception) {
+ logger.log(Level.WARNING, "Corrupted data in entity: " + e.getKey());
+ return null;
+ }
+ }
+
+ /**
+ * Convert a JSON object to a TestAcknowledgmentEntity.
+ *
+ * @param user The user requesting the conversion.
+ * @param json The json object to convert.
+ * @return TestAcknowledgmentEntity with the data from the json object.
+ */
+ public static TestAcknowledgmentEntity fromJson(User user, JsonObject json) {
+ try {
+ if (!json.has(TEST_NAME)) return null;
+ String testName = json.get(TEST_NAME).getAsString();
+ Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
+ List<String> branches = null;
+
+ Type listType = new TypeToken<List<String>>() {}.getType();
+ if (json.has(BRANCHES)) {
+ branches = new Gson().fromJson(json.get(BRANCHES), listType);
+ }
+
+ List<String> devices = null;
+ if (json.has(DEVICES)) {
+ devices = new Gson().fromJson(json.get(DEVICES), listType);
+ }
+
+ List<String> testCaseNames = null;
+ if (json.has(TEST_CASE_NAMES)) {
+ testCaseNames = new Gson().fromJson(json.get(TEST_CASE_NAMES), listType);
+ }
+
+ Text note = null;
+ if (json.has(NOTE)) {
+ note = new Text(json.get(NOTE).getAsString());
+ }
+
+ Key key = null;
+ if (json.has(KEY)) {
+ key = KeyFactory.stringToKey(json.get(KEY).getAsString());
+ }
+ return new TestAcknowledgmentEntity(
+ key, -1l, testKey, user, branches, devices, testCaseNames, note);
+ } catch (ClassCastException | IllegalStateException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Convert the entity to a json object.
+ *
+ * @return The entity serialized in JSON format.
+ */
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.add(KEY, new JsonPrimitive(KeyFactory.keyToString(this.key)));
+ json.add(TEST_NAME, new JsonPrimitive(this.test.getName()));
+ json.add(USER, new JsonPrimitive(this.user.getEmail()));
+ json.add(CREATED, new JsonPrimitive(this.created));
+
+ List<JsonElement> branches = new ArrayList<>();
+ if (this.branches != null) {
+ for (String branch : this.branches) {
+ branches.add(new JsonPrimitive(branch));
+ }
+ }
+ json.add(BRANCHES, new Gson().toJsonTree(branches));
+
+ List<JsonElement> devices = new ArrayList<>();
+ if (this.devices != null) {
+ for (String device : this.devices) {
+ devices.add(new JsonPrimitive(device));
+ }
+ }
+ json.add(DEVICES, new Gson().toJsonTree(devices));
+
+ List<JsonElement> testCaseNames = new ArrayList<>();
+ if (this.testCaseNames != null) {
+ for (String testCaseName : this.testCaseNames) {
+ testCaseNames.add(new JsonPrimitive(testCaseName));
+ }
+ }
+ json.add(TEST_CASE_NAMES, new Gson().toJsonTree(testCaseNames));
+
+ String note = "";
+ if (this.note != null) note = this.note;
+ json.add(NOTE, new JsonPrimitive(note));
+ return json;
+ }
+}
diff --git a/src/test/java/com/android/vts/entity/TestAcknowledgmentEntityTest.java b/src/test/java/com/android/vts/entity/TestAcknowledgmentEntityTest.java
new file mode 100644
index 0000000..85b5457
--- /dev/null
+++ b/src/test/java/com/android/vts/entity/TestAcknowledgmentEntityTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may
+ * obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.vts.entity;
+
+import static org.junit.Assert.*;
+
+import com.google.appengine.api.datastore.Entity;
+import com.google.appengine.api.datastore.Key;
+import com.google.appengine.api.datastore.KeyFactory;
+import com.google.appengine.api.datastore.Text;
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
+import com.google.gson.JsonObject;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAcknowledgmentEntityTest {
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(new LocalUserServiceTestConfig())
+ .setEnvIsAdmin(true)
+ .setEnvIsLoggedIn(true)
+ .setEnvEmail("testemail@domain.com")
+ .setEnvAuthDomain("test");
+
+ @Before
+ public void setUp() {
+ helper.setUp();
+ }
+
+ @After
+ public void tearDown() {
+ helper.tearDown();
+ }
+
+ /** Test serialization to/from Entity objects. */
+ @Test
+ public void testEntitySerialization() {
+ Key key = KeyFactory.createKey(TestEntity.KIND, "test");
+ User user = UserServiceFactory.getUserService().getCurrentUser();
+ List<String> branches = new ArrayList<>();
+ branches.add("branch1");
+ List<String> devices = new ArrayList<>();
+ devices.add("device1");
+ List<String> testCaseNames = new ArrayList<>();
+ testCaseNames.add("testCase1");
+ Text note = new Text("note");
+ TestAcknowledgmentEntity ack =
+ new TestAcknowledgmentEntity(key, user, branches, devices, testCaseNames, note);
+ Entity e = ack.toEntity();
+
+ Assert.assertNotNull(e);
+ Assert.assertEquals(key, e.getProperty(TestAcknowledgmentEntity.TEST_KEY));
+ Assert.assertEquals(user, e.getProperty(TestAcknowledgmentEntity.USER));
+ Assert.assertTrue(
+ ((List<String>) e.getProperty(TestAcknowledgmentEntity.BRANCHES))
+ .containsAll(branches));
+ Assert.assertTrue(
+ ((List<String>) e.getProperty(TestAcknowledgmentEntity.DEVICES))
+ .containsAll(devices));
+ Assert.assertTrue(
+ ((List<String>) e.getProperty(TestAcknowledgmentEntity.TEST_CASE_NAMES))
+ .containsAll(testCaseNames));
+ Assert.assertEquals(note, e.getProperty(TestAcknowledgmentEntity.NOTE));
+
+ TestAcknowledgmentEntity deserialized = TestAcknowledgmentEntity.fromEntity(e);
+ Assert.assertNotNull(deserialized);
+ Assert.assertEquals(key, deserialized.test);
+ Assert.assertEquals(user, deserialized.user);
+ Assert.assertTrue(deserialized.branches.containsAll(branches));
+ Assert.assertTrue(deserialized.devices.containsAll(devices));
+ Assert.assertTrue(deserialized.testCaseNames.containsAll(testCaseNames));
+ Assert.assertEquals(note.getValue(), deserialized.note);
+ }
+
+ /** Test serialization to/from Entity objects when optional parameters are null. */
+ @Test
+ public void testEntitySerializationWithNulls() {
+ Key key = KeyFactory.createKey(TestEntity.KIND, "test");
+ User user = UserServiceFactory.getUserService().getCurrentUser();
+ TestAcknowledgmentEntity ack =
+ new TestAcknowledgmentEntity(key, user, null, null, null, null);
+ Entity e = ack.toEntity();
+
+ Assert.assertNotNull(e);
+ Assert.assertEquals(key, e.getProperty(TestAcknowledgmentEntity.TEST_KEY));
+ Assert.assertEquals(user, e.getProperty(TestAcknowledgmentEntity.USER));
+ Assert.assertFalse(e.hasProperty(TestAcknowledgmentEntity.BRANCHES));
+ Assert.assertFalse(e.hasProperty(TestAcknowledgmentEntity.DEVICES));
+ Assert.assertFalse(e.hasProperty(TestAcknowledgmentEntity.TEST_CASE_NAMES));
+ Assert.assertFalse(e.hasProperty(TestAcknowledgmentEntity.NOTE));
+
+ TestAcknowledgmentEntity deserialized = TestAcknowledgmentEntity.fromEntity(e);
+ Assert.assertNotNull(deserialized);
+ Assert.assertEquals(key, deserialized.test);
+ Assert.assertEquals(user, deserialized.user);
+ Assert.assertEquals(0, deserialized.branches.size());
+ Assert.assertEquals(0, deserialized.devices.size());
+ Assert.assertEquals(0, deserialized.testCaseNames.size());
+ Assert.assertNull(deserialized.note);
+ }
+
+ /** Test serialization to/from Json objects. */
+ @Test
+ public void testJsonSerialization() {
+ Key key = KeyFactory.createKey(TestEntity.KIND, "test");
+ User user = UserServiceFactory.getUserService().getCurrentUser();
+ List<String> branches = new ArrayList<>();
+ branches.add("branch1");
+ List<String> devices = new ArrayList<>();
+ devices.add("device1");
+ List<String> testCaseNames = new ArrayList<>();
+ testCaseNames.add("testCase1");
+ Text note = new Text("note");
+ TestAcknowledgmentEntity ack =
+ new TestAcknowledgmentEntity(key, user, branches, devices, testCaseNames, note);
+ Entity e = new Entity(KeyFactory.createKey(TestAcknowledgmentEntity.KIND, "fakekey"));
+ e.setPropertiesFrom(ack.toEntity());
+ JsonObject json = TestAcknowledgmentEntity.fromEntity(e).toJson();
+
+ TestAcknowledgmentEntity deserialized = TestAcknowledgmentEntity.fromJson(user, json);
+ Assert.assertNotNull(deserialized);
+ Assert.assertEquals(key, deserialized.test);
+ Assert.assertEquals(user, deserialized.user);
+ Assert.assertTrue(deserialized.branches.containsAll(branches));
+ Assert.assertTrue(deserialized.devices.containsAll(devices));
+ Assert.assertTrue(deserialized.testCaseNames.containsAll(testCaseNames));
+ Assert.assertEquals(note.getValue(), deserialized.note);
+ }
+
+ /** Test serialization to/from Json objects when optional properties are null. */
+ @Test
+ public void testJsonSerializationWithNulls() {
+ Key key = KeyFactory.createKey(TestEntity.KIND, "test");
+ User user = UserServiceFactory.getUserService().getCurrentUser();
+ TestAcknowledgmentEntity ack =
+ new TestAcknowledgmentEntity(key, user, null, null, null, null);
+ Entity e = new Entity(KeyFactory.createKey(TestAcknowledgmentEntity.KIND, "fakekey"));
+ e.setPropertiesFrom(ack.toEntity());
+ JsonObject json = TestAcknowledgmentEntity.fromEntity(e).toJson();
+
+ TestAcknowledgmentEntity deserialized = TestAcknowledgmentEntity.fromJson(user, json);
+ Assert.assertNotNull(deserialized);
+ Assert.assertEquals(key, deserialized.test);
+ Assert.assertEquals(user, deserialized.user);
+ Assert.assertEquals(0, deserialized.branches.size());
+ Assert.assertEquals(0, deserialized.devices.size());
+ Assert.assertEquals(0, deserialized.testCaseNames.size());
+ Assert.assertEquals("", deserialized.note);
+ }
+}