commit d0d527fb38257701808411887eb6cf7d198df986
Author: Klaus Purer <klaus.purer@gmail.com>
Date:   Sat Mar 31 17:07:59 2012 +0200

    Added upgrade path tests and fixed block_role update.

diff --git a/core/includes/update.inc b/core/includes/update.inc
index e37cc90..f62eb50 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -250,7 +250,7 @@ function update_prepare_d8_role_names() {
     // upper case letters.
     foreach ($rid_mapping as $rid => $role_name) {
       $new_name = drupal_strtolower($role_name);
-      $new_name = preg_replace('/[^a-z0-9]/', '_', $new_name);
+      $new_name = preg_replace('/[^a-z0-9]/u', '_', $new_name);
       // Check if the new name already exists.
       do {
         $exists = db_select('role', 'r')
@@ -260,8 +260,22 @@ function update_prepare_d8_role_names() {
           ->execute()
           ->fetchCol();
         if (!empty($exists)) {
-          // Try again with an additional '_' until this name is unique.
-          $new_name = $new_name . '_';
+          if (drupal_strlen($new_name) < 64) {
+            // Try again with an additional '_' until this name is unique.
+            $new_name = $new_name . '_';
+          }
+          else {
+            // In the rare case that this is a long name and still not unique we
+            // just replace a random character at a random position.
+            $chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';
+            $new_name = substr_replace(
+              $new_name,
+              $chars[rand(0, strlen($chars) - 1)],
+              rand(0, strlen($new_name) - 1),
+              1
+            );
+
+          }
         }
       } while (!empty($exists));
 
diff --git a/core/modules/block/block.install b/core/modules/block/block.install
index 9f28608..10d7f24 100644
--- a/core/modules/block/block.install
+++ b/core/modules/block/block.install
@@ -205,7 +205,9 @@ function block_update_8001() {
   $column = array(
     'type' => 'varchar',
     'length' => 64,
-    'not null' => TRUE,
+    // Allow NULL values temporarily to be able to add the field for existing
+    // records.
+    'not null' => FALSE,
     'description' => "The role name from {role}.name.",
   );
   db_add_field('block_role', 'role_name', $column);
@@ -223,6 +225,10 @@ function block_update_8001() {
       ->execute();
   }
 
+  // The role name field must not be NULL.
+  $column['not null'] = TRUE;
+  db_change_field('block_role', 'role_name', 'role_name', $column);
+
   db_drop_field('block_role', 'rid');
   // Update the primary key of the block_role table.
   db_drop_primary_key('block_role');
diff --git a/core/modules/simpletest/simpletest.info b/core/modules/simpletest/simpletest.info
index cf55121..c34cc09 100644
--- a/core/modules/simpletest/simpletest.info
+++ b/core/modules/simpletest/simpletest.info
@@ -44,3 +44,4 @@ files[] = tests/upgrade/upgrade.test
 files[] = tests/upgrade/upgrade_bare.test
 files[] = tests/upgrade/upgrade_filled.test
 files[] = tests/upgrade/upgrade.language.test
+files[] = tests/upgrade/upgrade.roles.test
diff --git a/core/modules/simpletest/tests/upgrade/drupal-7.roles.database.php b/core/modules/simpletest/tests/upgrade/drupal-7.roles.database.php
new file mode 100644
index 0000000..a0ffe0a
--- /dev/null
+++ b/core/modules/simpletest/tests/upgrade/drupal-7.roles.database.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Database additions for role tests. Used in upgrade.roles.test.
+ *
+ * This dump only contains data and schema components relevant for role
+ * functionality. The drupal-7.bare.database.php file is imported before
+ * this dump, so the two form the database structure expected in tests
+ * altogether.
+ */
+
+db_insert('role')->fields(array(
+  'rid',
+  'name',
+  'weight',
+))
+// Adds a role with an umlaut in it.
+->values(array(
+  'rid' => '4',
+  'name' => 'gärtner',
+  'weight' => '3',
+))
+// Adds a very long role name.
+->values(array(
+  'rid' => '5',
+  'name' => 'very long role name that has exactly sixty-four characters in it',
+  'weight' => '4',
+))
+// Adds a very similar role name to test edge cases.
+->values(array(
+  'rid' => '6',
+  'name' => 'very_long role name that has exactly sixty-four characters in it',
+  'weight' => '5',
+))
+->execute();
+
+// Add the "Edit own comments" permission to the gärtner test role.
+db_insert('role_permission')->fields(array(
+  'rid',
+  'permission',
+  'module',
+))
+->values(array(
+  'rid' => '4',
+  'permission' => 'edit own comments',
+  'module' => 'comment',
+))
+->execute();
+
+// Adds some role visibility settings on the who's online block for the long
+// role.
+db_insert('block_role')->fields(array(
+  'module',
+  'delta',
+  'rid',
+))
+->values(array(
+  'module' => 'user',
+  'delta' => 'online',
+  'rid' => '5',
+))
+->execute();
diff --git a/core/modules/simpletest/tests/upgrade/upgrade.roles.test b/core/modules/simpletest/tests/upgrade/upgrade.roles.test
new file mode 100644
index 0000000..05c0854
--- /dev/null
+++ b/core/modules/simpletest/tests/upgrade/upgrade.roles.test
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @file
+ * Upgrade tests for the conversion of serial role IDs to role machine names.
+ */
+
+/**
+ * Tests upgrading a bare database with role data.
+ *
+ * Loads a bare installation of Drupal 7 with role data and runs the
+ * upgrade process on it.
+ */
+class RoleUpgradePathTestCase extends UpgradePathTestCase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'Role upgrade test',
+      'description'  => 'Upgrade tests with role data.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.database.php.gz',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.roles.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Tests a successful upgrade.
+   */
+  public function testRoleUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+    // Check that "gärtner" has been converted to "g_rtner" and that the role
+    // edit page for it exists.
+    $this->drupalGet('admin/people/permissions/roles/edit/g_rtner');
+    $this->assertResponse(200, 'Role edit page for "g_rtner" was found.');
+
+    // Check that the permission for "gärtner" still exists.
+    $this->drupalGet('admin/people/permissions/g_rtner');
+    $this->assertFieldChecked('edit-g-rtner-edit-own-comments', 'Edit own comments permission for "g_rtner" is set correctly.');
+
+    // Check that the role visibility setting for the who's online block still
+    // exists.
+    $this->drupalGet('admin/structure/block/manage/user/online/configure');
+    $this->assertFieldChecked('edit-roles-very-long-role-name-that-has-exactly-sixty-four-characters-in-it', "Who's online block visibility setting is correctly set for the long role name.");
+  }
+}
