diff --git a/core/lib/Drupal/Core/Entity/EntityChangedInterface.php b/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
index a8b1a61..f5ee395 100644
--- a/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
@@ -12,6 +12,12 @@
  *
  * This data may be useful for more precise cache invalidation (especially
  * on the client side) and concurrent editing locking.
+ *
+ * The entity system automatically adds in the 'EntityChanged' constraint for
+ * entity types implementing this interface in order to disallow concurrent
+ * editing.
+ *
+ * @see Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraint
  */
 interface EntityChangedInterface {
 
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 2b9c268..f9dc88c 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -227,6 +227,13 @@ class EntityType implements EntityTypeInterface {
   protected $list_cache_tags = [];
 
   /**
+   * Entity constraint definitions.
+   *
+   * @var array[]
+   */
+  protected $constraints = array();
+
+  /**
    * Constructs a new EntityType.
    *
    * @param array $definition
@@ -261,6 +268,12 @@ public function __construct($definition) {
       'access' => 'Drupal\Core\Entity\EntityAccessControlHandler',
     );
 
+    // Automatically add the EntityChanged constraint if the entity type tracks
+    // the changed time.
+    if ($this->isSubclassOf('Drupal\Core\Entity\EntityChangedInterface') ) {
+      $this->addConstraint('EntityChanged');
+    }
+
     // Ensure a default list cache tag is set.
     if (empty($this->list_cache_tags)) {
       $this->list_cache_tags = [$definition['id'] . '_list'];
@@ -741,4 +754,27 @@ public function isCommonReferenceTarget() {
     return $this->common_reference_target;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getConstraints() {
+    return $this->constraints;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConstraints(array $constraints) {
+    $this->constraints = $constraints;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addConstraint($constraint_name, $options = NULL) {
+    $this->constraints[$constraint_name] = $options;
+    return $this;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 101e372..6b68b01 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -693,4 +693,53 @@ public function getConfigDependencyKey();
    */
   public function isCommonReferenceTarget();
 
+  /**
+   * Returns an array of validation constraints.
+   *
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @return array[]
+   *   An array of validation constraint definitions, keyed by constraint name.
+   *   Each constraint definition can be used for instantiating
+   *   \Symfony\Component\Validator\Constraint objects.
+   *
+   * @see \Symfony\Component\Validator\Constraint
+   */
+  public function getConstraints();
+
+  /**
+   * Sets the array of validation constraints for the FieldItemList.
+   *
+   * NOTE: This will overwrite any previously set constraints. In most cases
+   * ContentEntityTypeInterface::addConstraint() should be used instead.
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @param array $constraints
+   *   An array of validation constraint definitions, keyed by constraint name.
+   *   Each constraint definition can be used for instantiating
+   *   \Symfony\Component\Validator\Constraint objects.
+   *
+   * @return $this
+   *
+   * @see \Symfony\Component\Validator\Constraint
+   */
+  public function setConstraints(array $constraints);
+
+  /**
+   * Adds a validation constraint.
+   *
+   * See \Drupal\Core\TypedData\DataDefinitionInterface::getConstraints() for
+   * details on how constraints are defined.
+   *
+   * @param string $constraint_name
+   *   The name of the constraint to add, i.e. its plugin id.
+   * @param array|null $options
+   *   The constraint options as required by the constraint plugin, or NULL.
+   *
+   * @return $this
+   */
+  public function addConstraint($constraint_name, $options = NULL);
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php
index 0c80fcf..7cea3c8 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Entity\Plugin\DataType\Deriver;
 
+use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -83,7 +84,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
     foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
       $this->derivatives[$entity_type_id] = array(
         'label' => $entity_type->getLabel(),
-        'constraints' => array('EntityType' => $entity_type_id),
+        'constraints' => $entity_type->getConstraints(),
       ) + $base_plugin_definition;
 
       // Incorporate the bundles as entity:$entity_type:$bundle, if any.
@@ -91,10 +92,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
         if ($bundle !== $entity_type_id) {
           $this->derivatives[$entity_type_id . ':' . $bundle] = array(
             'label' => $bundle_info['label'],
-            'constraints' => array(
-              'EntityType' => $entity_type_id,
-              'Bundle' => $bundle,
-            ),
+            'constraints' => $this->derivatives[$entity_type_id]['constraints']
           ) + $base_plugin_definition;
         }
       }
diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
index 9dd3628..fe81a63 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Entity\Plugin\Validation\Constraint;
 
-use Drupal\Core\Entity\EntityChangedInterface;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
 
@@ -19,14 +18,13 @@ class EntityChangedConstraintValidator extends ConstraintValidator {
   /**
    * {@inheritdoc}
    */
-  public function validate($value, Constraint $constraint) {
-    if (isset($value)) {
-      /** @var $entity \Drupal\Core\Entity\EntityInterface */
-      $entity = $this->context->getMetadata()->getTypedData()->getEntity();
+  public function validate($entity, Constraint $constraint) {
+    if (isset($entity)) {
+      /** @var \Drupal\Core\Entity\EntityInterface $entity */
       if (!$entity->isNew()) {
         $saved_entity = \Drupal::entityManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
 
-        if ($saved_entity && ($saved_entity instanceof EntityChangedInterface) && ($saved_entity->getChangedTime() > $value)) {
+        if ($saved_entity && $saved_entity->getChangedTime() > $entity->getChangedTime()) {
           $this->context->addViolation($constraint->message);
         }
       }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php
index cafdde7..81625d4 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php
@@ -10,16 +10,18 @@
 /**
  * Defines the 'changed' entity field type.
  *
+ * Based on a field of this type, entity types can easily implement the
+ * EntityChangedInterface.
+ *
  * @FieldType(
  *   id = "changed",
  *   label = @Translation("Last changed"),
  *   description = @Translation("An entity field containing a UNIX timestamp of when the entity has been last updated."),
  *   no_ui = TRUE,
- *   list_class = "\Drupal\Core\Field\ChangedFieldItemList",
- *   constraints = {
- *     "ComplexData" = {"value" = {"EntityChanged" = {}}}
- *   }
+ *   list_class = "\Drupal\Core\Field\ChangedFieldItemList"
  * )
+ *
+ * @see \Drupal\Core\Entity\EntityChangedInterface
  */
 class ChangedItem extends CreatedItem {
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
index 81664ba..22bea73 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EntityReferenceItem.php
@@ -91,12 +91,17 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
       // The entity object is computed out of the entity ID.
       ->setComputed(TRUE)
       ->setReadOnly(FALSE)
-      ->setTargetDefinition(EntityDataDefinition::create($settings['target_type']));
+      ->setTargetDefinition(EntityDataDefinition::create($settings['target_type']))
+      ->addConstraint('EntityType', $settings['target_type']);
 
     if (isset($settings['target_bundle'])) {
-      $properties['entity']->getTargetDefinition()->addConstraint('Bundle', $settings['target_bundle']);
+      $properties['entity']->addConstraint('Bundle', $settings['target_bundle']);
+      // Set any further bundle constraints on the target definition as well,
+      // such that it can derive more special data types if possible. For
+      // example, "entity:node:page" instead of "entity:node".
+      $properties['entity']->getTargetDefinition()
+        ->addConstraint('Bundle', $settings['target_bundle']);
     }
-
     return $properties;
   }
 
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index c5a227b..fb75edc 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -400,10 +400,6 @@ public function getDefaultConstraints(DataDefinitionInterface $definition) {
     if (is_subclass_of($definition->getClass(),'Drupal\Core\TypedData\OptionsProviderInterface')) {
       $constraints['AllowedValues'] = array();
     }
-    // Add any constraints about referenced data.
-    if ($definition instanceof DataReferenceDefinitionInterface) {
-      $constraints += $definition->getTargetDefinition()->getConstraints();
-    }
     return $constraints;
   }
 
diff --git a/core/modules/node/src/Tests/NodeValidationTest.php b/core/modules/node/src/Tests/NodeValidationTest.php
index ef11740..b38af1c 100644
--- a/core/modules/node/src/Tests/NodeValidationTest.php
+++ b/core/modules/node/src/Tests/NodeValidationTest.php
@@ -63,7 +63,7 @@ public function testValidation() {
     $node->set('changed', 433918800);
     $violations = $node->validate();
     $this->assertEqual(count($violations), 1, 'Violation found when changed date is before the last changed date.');
-    $this->assertEqual($violations[0]->getPropertyPath(), 'changed.0.value');
+    $this->assertEqual($violations[0]->getPropertyPath(), '');
     $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
   }
 }
diff --git a/core/modules/quickedit/src/Form/QuickEditFieldForm.php b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
index 54e7170..71bd1c5 100644
--- a/core/modules/quickedit/src/Form/QuickEditFieldForm.php
+++ b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
@@ -18,6 +18,7 @@
 use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\user\PrivateTempStoreFactory;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Validator\ValidatorInterface;
 
 /**
  * Builds and process a form for editing a single entity field.
@@ -46,6 +47,13 @@ class QuickEditFieldForm extends FormBase {
   protected $nodeTypeStorage;
 
   /**
+   * The typed data validator.
+   *
+   * @var \Symfony\Component\Validator\ValidatorInterface
+   */
+  protected $validator;
+
+  /**
    * Constructs a new EditFieldForm.
    *
    * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
@@ -54,11 +62,14 @@ class QuickEditFieldForm extends FormBase {
    *   The module handler.
    * @param \Drupal\Core\Entity\EntityStorageInterface $node_type_storage
    *   The node type storage.
+   * @param \Symfony\Component\Validator\ValidatorInterface $validator
+   *   The typed data validator service.
    */
-  public function __construct(PrivateTempStoreFactory $temp_store_factory, ModuleHandlerInterface $module_handler, EntityStorageInterface $node_type_storage) {
+  public function __construct(PrivateTempStoreFactory $temp_store_factory, ModuleHandlerInterface $module_handler, EntityStorageInterface $node_type_storage, ValidatorInterface $validator) {
     $this->moduleHandler = $module_handler;
     $this->nodeTypeStorage = $node_type_storage;
     $this->tempStoreFactory = $temp_store_factory;
+    $this->validator = $validator;
   }
 
   /**
@@ -68,7 +79,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('user.private_tempstore'),
       $container->get('module_handler'),
-      $container->get('entity.manager')->getStorage('node_type')
+      $container->get('entity.manager')->getStorage('node_type'),
+      $container->get('typed_data_manager')->getValidator()
     );
   }
 
@@ -148,14 +160,16 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
 
     $form_state->get('form_display')->validateFormValues($entity, $form, $form_state);
 
-    // Do validation on the changed field as well and assign the error to the
-    // dummy form element we added for this. We don't know the name of this
-    // field on the entity, so we need to find it and validate it ourselves.
-    if ($changed_field_name = $this->getChangedFieldName($entity)) {
-      $changed_field_errors = $entity->$changed_field_name->validate();
-      if (count($changed_field_errors)) {
-        $form_state->setErrorByName('changed_field', $changed_field_errors[0]->getMessage());
-      }
+    // Run entity-level validation as well, while skipping validation of all
+    // fields. We can do so by fetching and validating the entity-level
+    // constraints manually.
+    // @todo: Improve this in https://www.drupal.org/node/2395831.
+    $typed_entity = $entity->getTypedData();
+    $violations = $this->validator
+      ->validateValue($typed_entity, $typed_entity->getConstraints());
+
+    foreach ($violations as $violation) {
+      $form_state->setErrorByName($violation->getPropertyPath(), $violation->getMessage());
     }
   }
 
@@ -235,21 +249,4 @@ protected function simplify(array &$form, FormStateInterface $form_state) {
     }
   }
 
-  /**
-   * Finds the field name for the field carrying the changed timestamp, if any.
-   *
-   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
-   *   The entity.
-   *
-   * @return string|null
-   *   The name of the field found or NULL if not found.
-   */
-  protected function getChangedFieldName(FieldableEntityInterface $entity) {
-    foreach ($entity->getFieldDefinitions() as $field) {
-      if ($field->getType() == 'changed') {
-        return $field->getName();
-      }
-    }
-  }
-
 }
diff --git a/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php b/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php
new file mode 100644
index 0000000..9519143
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/EntityTypeConstraintsTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\Entity\EntityTypeConstraintsTest.
+ */
+
+namespace Drupal\system\Tests\Entity;
+
+use Drupal\system\Tests\TypedData;
+
+/**
+ * Tests entity level validation constraints.
+ *
+ * @group Entity
+ */
+class EntityTypeConstraintsTest extends EntityUnitTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('entity_test_constraints');
+  }
+
+  /**
+   * Tests defining entity constraints via entity type annotations and hooks.
+   */
+  public function testConstraintDefinition() {
+    // Test reading the annotation. There should be two constraints, the defined
+    // constraint and the automatically added EntityChanged constraint.
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $default_constraints = ['NotNull' => [], 'EntityChanged' => NULL];
+    $this->assertEqual($default_constraints, $entity_type->getConstraints());
+
+    // Enable our test module and test extending constraints.
+    $this->enableModules(array_merge(static::$modules, ['entity_test_constraints']));
+    $this->container->get('module_handler')->resetImplementations();
+
+    $extra_constraints = ['Test' => []];
+    $this->state->set('entity_test_constraints.build', $extra_constraints);
+    // Re-fetch the entity manager from the new container built after the new
+    // modules were enabled.
+    $this->entityManager = $this->container->get('entity.manager');
+    $this->entityManager->clearCachedDefinitions();
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $this->assertEqual($default_constraints + $extra_constraints, $entity_type->getConstraints());
+
+    // Test altering constraints.
+    $altered_constraints = ['Test' => [ 'some_setting' => TRUE]];
+    $this->state->set('entity_test_constraints.alter', $altered_constraints);
+    // Clear the cache in state instance in the Drupal container, so it can pick
+    // up the modified value.
+    \Drupal::state()->resetCache();
+    $this->entityManager->clearCachedDefinitions();
+    $entity_type = $this->entityManager->getDefinition('entity_test_constraints');
+    $this->assertEqual($altered_constraints, $entity_type->getConstraints());
+  }
+
+  /**
+   * Tests entity constraints are validated.
+   */
+  public function testConstraintValidation() {
+    $entity = $this->entityManager->getStorage('entity_test_constraints')->create();
+    $entity->user_id->target_id = 0;
+    $violations = $entity->validate();
+    $this->assertEqual($violations->count(), 0, 'Validation passed.');
+    $entity->save();
+    $entity->changed->value = REQUEST_TIME - 86400;
+    $violations = $entity->validate();
+    $this->assertEqual($violations->count(), 1, 'Validation failed.');
+    $this->assertEqual($violations[0]->getMessage(), t('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'));
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php
new file mode 100644
index 0000000..9f92e7a
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraints.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\entity_test\Entity\EntityTestConstraints.
+ */
+
+namespace Drupal\entity_test\Entity;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+
+/**
+ * Defines a test class for testing the definition of entity level constraints.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_constraints",
+ *   label = @Translation("Test entity constraints"),
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid",
+ *     "bundle" = "type",
+ *     "label" = "name"
+ *   },
+ *   base_table = "entity_test_constraints",
+ *   persistent_cache = FALSE,
+ *   constraints = {
+ *     "NotNull" = {}
+ *   }
+ * )
+ */
+class EntityTestConstraints extends EntityTest implements EntityChangedInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    $fields['changed'] = BaseFieldDefinition::create('changed')
+      ->setLabel(t('Changed'));
+
+    return $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getChangedTime() {
+    return $this->get('changed')->value;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml
new file mode 100644
index 0000000..5b08087
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.info.yml
@@ -0,0 +1,8 @@
+name: 'Entity constraints test module'
+type: module
+description: 'Tests extending and altering entity constraints.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - entity_test
diff --git a/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module
new file mode 100644
index 0000000..684ffb3
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_constraints/entity_test_constraints.module
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * @file
+ * Test module file.
+ */
+
+/**
+ * Implements hook_entity_type_build().
+ */
+function entity_test_constraints_entity_type_build(array &$entity_types) {
+  if ($extra = \Drupal::state()->get('entity_test_constraints.build')) {
+    foreach ($extra as $id => $option) {
+      $entity_types['entity_test_constraints']->addConstraint($id, $option);
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function entity_test_constraints_entity_type_alter(array &$entity_types) {
+  if ($alter = \Drupal::state()->get('entity_test_constraints.alter')) {
+    $entity_types['entity_test_constraints']->setConstraints($alter);
+  }
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
index 6a61fa1..c350b48 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
@@ -251,4 +251,25 @@ public function testSetLinkTemplateWithInvalidPath() {
     $entity_type->setLinkTemplate('test', 'invalid-path');
   }
 
+  /**
+   * Tests the constraint methods.
+   *
+   * @covers ::getConstraints
+   * @covers ::setConstraints
+   * @covers ::addConstraint
+   */
+  public function testConstraintMethods() {
+    $definition = [
+      'constraints' => [
+        'EntityChanged' => [],
+      ],
+    ];
+    $entity_type = $this->setUpEntityType($definition);
+    $this->assertEquals($definition['constraints'], $entity_type->getConstraints());
+    $entity_type->addConstraint('Test');
+    $this->assertEquals($definition['constraints'] + ['Test' => NULL], $entity_type->getConstraints());
+    $entity_type->setConstraints([]);
+    $this->assertEquals([], $entity_type->getConstraints());
+  }
+
 }
