Manual data migration from Data center to Cloud

Manual data migration from Data center to Cloud

The migration of QAlity Plus data from the Data Center to Cloud Jira instances is not supported. However, we can offer a workaround to do it manually using our QAlity Plus REST API. QAlity Plus REST API documentation

Please note that using Jira Cloud Migration Assistant (JCMA) to migrate the QAlity Plus Test Cases will result in incomplete data. JCMA will only migrate the Test Case work items themselves, without any additional details such as Test Steps, Test Cycles, Test Executions, or Test Execution Statuses, etc.

If you encounter problems during the migration process, contact our QAlity Plus Support.

Manual Data Migration – Step-by-Step Instructions:

  1. Export Data from Data Center
    Retrieve all relevant App data from your existing Data Center instance database by SQL queries.

  2. Transform and Prepare Data
    Adjust the data format to match the structure expected by the Cloud API. Ensure all required fields are present and IDs are mapped correctly where necessary.

  3. Authentication with the Cloud API
    Authenticate your requests to the Cloud environment. Make sure you are authorized to make specified requests. Each endpoint describes what permissions are needed.

  4. Upload Data to Cloud
    Use the appropriate Cloud API endpoints to import your data into the new Cloud instance. If needed, perform this in batches and validate responses to ensure successful uploads.


QAlity Plus Data Center Database Schema

image-20250513-105426.png

🔍 Understanding QAlity Plus Test Case Versioning

Before diving into the migration process, it's important to understand how the Test Case Versioning system in QAlty Plus works:

  1. Test Case and Test Steps Creation

    • When a Test Case is created, a Test Case Version object is not created with it.

    • When Test Steps are added, new test step objects are created and linked to the Test Case by TEST_CASE_ID. The most recent steps have VERSION_ID=NULL.

  2. Test Case Execution

    • When you execute the Test Case, a snapshot of its current state (summary, Test Steps) is captured and saved as a new object Test Case Version (e.g., V1).

    • Newest Test Steps (with null VERSION_ID) will be copied and linked to Test Case Version V1 by VERSION_ID

    • For each Test Step in this version, a corresponding Test Execution Step is created and linked to the new Test Execution by TEST_EXECUTION_ID.

  3. Modifying the Test Case

    • If you modify the Test Case (e.g., add or rename steps), the Test Steps of V1 will not be modified. The execution already created will stay with the same data.

  4. Second Execution

    • When you create another Test Execution after the modification, a new Test Case Version (e.g., V2) is created, capturing the updated state of the Test Case.

    • Meanwhile, the first execution remains linked to Version V1, preserving the original structure.


Data migration order

  1. Jira Work Items, Versions, Users, and Projects

  2. Test Execution Statuses

  3. Test Cycles

  4. Test Case Executions + Test Case data (Test Steps)

  5. Folders


Migrating Jira Work Items, Versions, Users, Attachments, and Projects

To migrate projects, work items, versions, and users, use JCMA. The ID of each migrated object will be different on the Cloud from the Data Center one. To successfully transfer QAlity Plus Data, we need to create a mapping between the Data Center ID and Cloud ID. Use Jira REST API to fetch data from the cloud instance.

  1. Project Mapping - Match projects between the Data Center and the Cloud by project key. Create a PROJECT_MAP where Data Center project IDs are mapped to their corresponding Cloud project IDs. Example script:

  2. Version Mapping - Match versions between Data Center and Cloud by name - Create a VERSION_MAP where Data Center version IDs are mapped to their corresponding Cloud version IDs.

  3. Test Case Mapping - Match test cases between Data Center and Cloud by work item key. Create a TEST_CASE_MAP where Data Center test case IDs are mapped to their corresponding Cloud test case IDs.

  4. User Mapping - Match Users between Data Center and Cloud by display name. Create a USER_MAP where Data Center user IDs are mapped to their corresponding Cloud user IDs.


Migrating Test Execution Statuses

  1. Fetch the Test Execution Status data directly from the Data Center database table AO_A89232_STATUS using a SQL query.

  2. For each status retrieved, create a matching one in the Cloud using the endpoint - POST /statuses. Create a STATUS_MAP where Data Center Test Execution Status IDs are mapped to their corresponding Cloud Test Execution Status IDs.

  3. The create status endpoint does not take any params; it creates a status with the default parameters. To change the name, category, and position, update it using - PATCH /statuses/{statusId}

  4. Note on Default Statuses - The Cloud environment creates a set of default test execution statuses. If any of the statuses from the Data Center have the same name as these default ones (Passed, Failed, Blocked, In progress, Unexecuted), they will not be created on the Cloud because status names must be unique. In this case, there is no need to create a new status; just save the corresponding ID to STATUS_MAP to match status by name.

  5. Example Python script that can be used for migrating test execution statuses:


Migrating Test Cycles

  1. Fetch test cycles from the Data Center table AO_A89232_TEST_CYCLE using SQL query.

  2. Create test cycles on the Cloud using POST /testCycles.

    1. Test Cycle Name, dueDate, and comment parameters should be the values fetched from the AO_A89232_TEST_CYCLE table

    2. Test Cycle versionId parameter should be the value fetched from the AO_A89232_TEST_CYCLE table, but mapped to the cloud ID by using VERSION_MAP.

    3. Test Cycle projectIDparameter should be value fetched from AO_A89232_TEST_CYCLE table, but mapped to cloud ID by using PROJECT_MAP.

  3. Save the IDs of the created Test Cycle objects on Cloud and match their IDs to Test Cycles from Data Center Database values and save them into TEST_CYCLES_MAP.

  4. To migrate other attributes of Test Cycle, use endpoint PATCH /testCycles/{testCycleId} with mapped Test Cycle IDs from TEST_CYCLES_MAP.

    1. isClosed parameter value should be fetched from the AO_A89232_TEST_CYCLE table.


Migrating Test Case Executions

If you want to export only the newest test case versions, use this quick guide: Migration of Test Cases from Data Center to Cloud. If you need the historical data, use the guide below.

  1. There is no direct way to create a Test Case Version object on Cloud via the REST API. To create the correct Test Case Version, we need to recreate the Test Step Data of the specified Test Case at the time of the execution and create the Test Case Execution object to snapshot the state of the Test Steps.

  2. Fetch Test Step Data from Data Center Database table AO_A89232_TEST_STEP using SQL and group them by VERSION_ID, sorted in descending order. Test Steps with NULL version are the newest; the lower the version number, the older it is.

  3. Save the test steps in TEST_STEPS_BY_VERSION_MAP, where VERSION_ID is the key and the Array of test steps is the value.

  4. Get Test Case Executions from the Data Center Database table AO_A89232_TEST_EXECUTION using SQL and sort them in descending order by CREATED_DATE

    1. Group Test Executions by VERSION_ID.

    2. For each VERSION_ID:

      1. Change the summary of The Cloud Test Case to the NAME attribute from Test Execution. Test Case ID should be taken from TEST_CASE_MAP. Using the Edit Issue endpoint from the Jira REST API - Edit Issue Endpoint.

      2. Fetch Test Steps from the Data Center Database table AO_A89232_TEST_STEP with the given VERSION_ID

      3. Populate the Test Step data via the endpoint. POST Test Steps. There is no need to populate Test Steps that already exist.

      4. For each Test Execution with that VERSION_ID

        1. If the Test Execution is in cycle

          1. Retrieve the cloud test cycle ID from TEST_CYCLE_MAP

          2. Create the test execution via endpoint POST /testCycleAssignment,

          3. Retrieve the Test Execution ID from the response.

          4. Then update the Attributes of the test execution using PATCH /testExecutions/{testExecutionId}

          5. COMMENT - value from Data Center Database table AO_A89232_TEST_EXECUTION

          6. EXECUTION_ASSIGNEE - value from Data Center Database table AO_A89232_TEST_EXECUTION mapped with USER_MAP

          7. STATUS_ID- value from Data Center Database table AO_A89232_TEST_EXECUTION mapped with STATUS_MAP

          8. Save the ID attribute from the response of the assignment endpoint, it is the ID of the object table AO_A89232_TEST_CASE_IN_CYCLE. Create TEST_CASE_IN_CYCLE_MAP and map Data Center IDs to cloud ones.

        2. If the Test Execution is Ad hoc

          1. Create Test Execution using POST /testExecutions

          2. Payload :

            1. testCaseId should be taken from the value from table AO_A89232_TEST_EXECUTION mapped with TEST_CASE_MAP

            2. executionAssignee should be taken from the value from the table AO_A89232_TEST_EXECUTION mapped with the USER_MAP

            3. name, comment should be value from table AO_A89232_TEST_EXECUTION

            4. testCaseInCycleId should be NULL

            5. statusId should be taken from the value from the table AO_A89232_TEST_EXECUTION mapped with STATUS_MAP

        3. Migrate Test Execution Steps. Fetch Test Execution steps from Data Center Table AO_A89232_TEST_EXECUTION_STEP

          1. Fetch test execution steps from the created Test Execution on the Cloud using GET /testExecutions/{testExecutionId}

          2. Match their IDs to the Data Center ones by POSITION. Save this information in TEST_EXECUTION_STEP_MAP

          3. Update Test Execution Steps on Cloud using TEST_EXECUTION_STEP_MAP and endpoint PATCH /testExecutionStep

            1. statusId should be taken from the value from the table AO_A89232_TEST_EXECUTION_STEP and mapped to the cloud with STATUS_MAP

            2. comment should be taken from the value in the table AO_A89232_TEST_EXECUTION_STEP

            3. attachments - not supported.

          4. Additionally, you can map the linked issues to Test Execution Steps USING POST /linkedIssues. Issue ID should be taken from Data Center database, but mapped to Cloud ID by issue Key.

        4. Save the ID of the created Test Execution to the TEST_EXECUTION_MAP. It will be useful if you want to migrate the test Execution Creation date later.

        5. Repeat this process for Each Test Execution with the given VERSION_ID

      5. Repeat this process for each VERSION_ID

      6. Alter the positions of Test Cases in the Test Cycle using the endpoint:

        PUT /testCasesInCyclePosition payload: { testCases[ { "id": TEST_CASE_IN_CYCLE_ID, "position": POSITION }, ], testCycleId: TEST_CYCLE_ID }

        Use IDs from TEST_CASE_IN_CYCLE_MAP. The value of the position should be taken from AO_A89232_TEST_CASE_IN_CYCLE.

         

Unfortunately, it's not possible to migrate the Test Execution creation date through the REST API, as this value is automatically set to the time the endpoint is called.

If preserving the original creation date is important for your migration, please reach out to our QAlity Plus Support for further assistance.


Migrating Folders

  1. Fetch Folders from the Data Center table AO_A89232_FOLDER using SQL.

  2. Folders have a tree structure, the migration will need to use the recursive algorithm.

  3. Create a Folder Object using endpoint - POST /folders. Start from Folder Objects where PARENT_ID is NULL. Pseudo code:

Function migrateFolder(dcFolderId, parentCloudId = null): 1. Fetch folder row from AO_A89232_FOLDER where ID = dcFolderId 2. Get: - folderName = NAME - projectIdDC = PROJECT_ID - children = all folders where PARENT_ID = dcFolderId 3. Map projectIdDC to projectIdCloud using PROJECT MAP 4. Prepare payload: { name: folderName, projectId: projectIdCloud, parentId: parentCloudId, testCaseIds: null } 5. Call POST /folders with payload → Save returned cloudFolderId in a map: FOLDER_MAP[dcFolderId] = cloudFolderId 6. For each child in children: migrateFolder(child.ID, cloudFolderId)
  1. Assigning test cases to folders - Fetch Test Case in Folder objects from DC table AO_A89232_TEST_CASE_IN_FOLDER using SQL.

  2. For each TEST_CASE_IN_FOLDER row:

    1. Params - folderId- FOLDER_MAP[dcFolderId]

    2. Payload -

      { "testCasesIds": TEST CASE MAP[dcTestCaseId] }
    3. Execute endpoint POST /folderAssignment, with given params and payload.