Update Robot Framework format - step 5
[integration/test.git] / csit / suites / controller / akka_upgrade / 1node.robot
1 *** Settings ***
2 Documentation       Suite for testing upgrading persisted data from earlier release.
3 ...
4 ...                 Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
5 ...
6 ...                 This program and the accompanying materials are made available under the
7 ...                 terms of the Eclipse Public License v1.0 which accompanies this distribution,
8 ...                 and is available at http://www.eclipse.org/legal/epl-v10.html
9 ...
10 ...
11 ...                 This suite kills the running (newer) ODL at its default location.
12 ...                 It then installs (configurable) older ODL to an alternative location,
13 ...                 pushes large amount of car data, verifies and kills the older ODL.
14 ...                 The journal and snapshot files are transferred to the default location
15 ...                 and the newer ODL is started.
16 ...                 Then it verifies the config data is still present and matches what was seen before.
17 ...
18 ...                 In principle, the suite should also work if "newer" ODL is in fact older.
19 ...                 The limiting factor is featuresBoot, the value should be applicable to both ODL versions.
20 ...
21 ...                 Note that in order to create traffic large enough for snapshots to be created,
22 ...                 this suite also actis as a stress test for Restconf.
23 ...                 But as that is not a primary focus of this suite,
24 ...                 data seen on newer ODL is only compared to what was seen on the older ODL
25 ...                 (stored in ${data_before} suite variable).
26 ...
27 ...                 As using Robotframework would be both too slow and too memory consuming,
28 ...                 this suite uses a specialized Python utility for pushing the data locally on ODL_SYSTEM.
29 ...                 The utility filename is configurable, as there may be changes in PATCH behavior in future.
30 ...
31 ...                 This suite uses relatively new support for PATCH http method.
32 ...                 It repetitively replaces a segment of cars with moving IDs,
33 ...                 so that there is a lot of data in journal (both write and delete),
34 ...                 but the overall size of data stored remains limited.
35 ...
36 ...                 This is 1-node suite, but it still uses ClusterManagement.Check_Cluster_Is_In_Sync
37 ...                 in order to detect the same sync condition as 3-node suite would do.
38 ...                 Jolokia feature is required for that.
39 ...
40 ...                 Minimal set of features to be installed: odl-restconf, odl-jolokia, odl-clustering-test-app.
41
42 Library             String
43 Library             SSHLibrary
44 Resource            ${CURDIR}/../../../libraries/CompareStream.robot
45 Resource            ${CURDIR}/../../../libraries/ClusterManagement.robot
46 Resource            ${CURDIR}/../../../libraries/SetupUtils.robot
47 Resource            ${CURDIR}/../../../libraries/SSHKeywords.robot
48 Resource            ${CURDIR}/../../../libraries/TemplatedRequests.robot
49 Resource            ${CURDIR}/../../../libraries/NexusKeywords.robot
50
51 Suite Setup         Setup_Suite
52 Test Setup          SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
53 Test Teardown       SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
54
55 Default Tags        1node    carpeople    critical
56
57
58 *** Variables ***
59 ${ALTERNATIVE_BUNDLEFOLDER_PARENT}      /tmp/older
60 ${CAR_VAR_DIR}                          ${CURDIR}/../../../variables/carpeople/libtest/cars
61 # Rebooting after kill may take longer time, especially for -all- install.
62 ${CLUSTER_BOOTUP_SYNC_TIMEOUT}
63 ...                                     1200s
64 ${ITERATIONS}                           1000
65 ${MOVE_PER_ITER}                        1000
66 ${PREVIOUS_ODL_RELEASE_ZIP_URL}         ${EMPTY}
67 ${PYTHON_UTILITY_FILENAME}              replace_cars.py
68 ${SEGMENT_SIZE}                         10000
69
70
71 *** Test Cases ***
72 Select_Latest_Previous_Release_If_Not_Specified
73     [Documentation]    If previous ODL release is not specified, then latest release for previous to current stream is used.
74     ...    Note: If current stream is not found on nexus, then it is taken as new one (not released yet).
75     ...    So in this case, latest release version is return.
76     BuiltIn.Set_Suite_Variable    ${odl_zip_url}    ${PREVIOUS_ODL_RELEASE_ZIP_URL}
77     BuiltIn.Pass_Execution_If
78     ...    '${odl_zip_url}'!=''
79     ...    Bundle url to previous release is provided: ${PREVIOUS_ODL_RELEASE_ZIP_URL}, no need to search in nexus.
80     ${previous_release} =    NexusKeywords.Get_Latest_ODL_Previous_Stream_Release_URL    ${ODL_STREAM}
81     BuiltIn.Set_Suite_Variable    ${odl_zip_url}    ${previous_release}
82
83 Kill_Original_Odl
84     [Documentation]    The ODL prepared by releng/builder is the newer one, kill it.
85     ...    Also, remove journal and snapshots.
86     ClusterManagement.Kill_Members_From_List_Or_All
87     # This is deliberately analoguous to killing the whole cluster.
88     # (As opposed to killing just one member, but for 1 node it is the same.)
89     ClusterManagement.Clean_Journals_Data_And_Snapshots_On_List_Or_All
90
91 Install_Older_Odl
92     [Documentation]    Download .zip of older ODL, unpack, delete .zip, copy featuresBoot line.
93     # Download.
94     SSHKeywords.Execute_Command_Should_Pass
95     ...    mkdir -p "${ALTERNATIVE_BUNDLEFOLDER_PARENT}" && cd "${ALTERNATIVE_BUNDLEFOLDER_PARENT}" && rm -rf * && wget -N "${odl_zip_url}"
96     # Unzip and detect bundle folder name.
97     ${bundle_dir} =    SSHKeywords.Execute_Command_Should_Pass
98     ...    cd "${ALTERNATIVE_BUNDLEFOLDER_PARENT}" && unzip -q *.zip && rm *.zip && ls -1
99     BuiltIn.Set_Suite_Variable    \${alternative_bundlefolder}    ${ALTERNATIVE_BUNDLEFOLDER_PARENT}/${bundle_dir}
100     # TODO: Add more strict checks. Folder should have single line, without .zip extension.
101     # Extract featuresBoot lines.
102     ${cfg_filename} =    BuiltIn.Set_Variable    org.apache.karaf.features.cfg
103     ${cfg_older} =    BuiltIn.Set_Variable    ${alternative_bundlefolder}/etc/${cfg_filename}
104     ${cfg_newer} =    BuiltIn.Set_Variable    ${WORKSPACE}/${BUNDLEFOLDER}/etc/${cfg_filename}
105     ${vanilla_line} =    SSHKeywords.Execute_Command_Should_Pass
106     ...    grep 'featuresBoot' "${cfg_older}" | grep -v 'featuresBootAsynchronous'
107     ${csit_line} =    SSHKeywords.Execute_Command_Should_Pass
108     ...    grep 'featuresBoot' "${cfg_newer}" | grep -v 'featuresBootAsynchronous'
109     ${karaf4_features} =    Extract_Karaf4_Boot_Features    ${csit_line}
110     # TODO: this works only if old odl is karaf3. Once old and new odl both are e.g. karaf4 this will create invalid line.
111     ${new_csit_line} =    CompareStream.Set_Variable_If_At_Least_Nitrogen
112     ...    ${vanilla_line},${karaf4_features}
113     ...    ${csit_line}
114     # Replace the vanilla line.
115     SSHKeywords.Execute_Command_Should_Pass    sed -i 's/${vanilla_line}/${new_csit_line}/g' "${cfg_older}"
116     # Verify the replaced line.
117     ${updated_line} =    SSHKeywords.Execute_Command_Should_Pass
118     ...    grep 'featuresBoot' "${cfg_older}" | grep -v 'featuresBootAsynchronous'
119     BuiltIn.Should_Not_Be_Equal    ${vanilla_line}    ${updated_line}
120     BuiltIn.Should_Be_Equal    ${new_csit_line}    ${updated_line}
121
122 Start_Older_Odl
123     [Documentation]    Start older ODL on background.
124     [Tags]    1node    carpeople    # Not critical, to save space in default log.html presentation
125     ClusterManagement.Start_Members_From_List_Or_All
126     ...    wait_for_sync=True
127     ...    timeout=${CLUSTER_BOOTUP_SYNC_TIMEOUT}
128     ...    karaf_home=${alternative_bundlefolder}
129
130 Add_Data
131     [Documentation]    Put car data to config datastore of older ODL.
132     ${command} =    BuiltIn.Set_Variable
133     ...    python ${PYTHON_UTILITY_FILENAME} --segment-size=${SEGMENT_SIZE} --iterations=${ITERATIONS} --move-per-iter=${MOVE_PER_ITER}
134     SSHKeywords.Execute_Command_Should_Pass    ${command}    stderr_must_be_empty=True
135     # TODO: I have seen 401 here once. Implement workaround or report a Bug.
136
137 Remember_Data
138     [Documentation]    Get and save the stored data for later comparison.
139     ${data} =    TemplatedRequests.Get_As_Json_Templated    folder=${CAR_VAR_DIR}    verify=False
140     BuiltIn.Set_Suite_Variable    \${data_before}    ${data}
141
142 Validate_Data
143     [Documentation]    Compare the saved data against what the data should look like.
144     ${first_id} =    BuiltIn.Evaluate    (${ITERATIONS} - 1) * ${MOVE_PER_ITER} + 1
145     SetupUtils.Set_Known_Bug_Id    5909
146     # The following line is the second part of TemplatedRequests.Get_As_Json_Templated for verify=True.
147     TemplatedRequests.Verify_Response_As_Json_Templated
148     ...    response=${data_before}
149     ...    folder=${CAR_VAR_DIR}
150     ...    base_name=data
151     ...    iterations=${SEGMENT_SIZE}
152     ...    iter_start=${first_id}
153
154 Kill_Older_Odl
155     [Documentation]    Kill the older ODL immediatelly.
156     ClusterManagement.Kill_Members_From_List_Or_All
157
158 Transfer_Persisted_Data
159     [Documentation]    Move snapshots and (segmented-)journal into the original ODL installation.
160     # SSHLibrary.Switch_Connection    ${odl_system_ssh_index}
161     ${stdout} =    SSHKeywords.Execute_Command_Should_Pass
162     ...    cp -rv "${alternative_bundlefolder}/snapshots" "${WORKSPACE}/${BUNDLEFOLDER}/" && cp -rv "${alternative_bundlefolder}/"*journal "${WORKSPACE}/${BUNDLEFOLDER}/"
163     Set_Suite_Variable    ${stdout}
164
165 Check_Snapshot_With_Transferred_Persisted_Data
166     [Documentation]    Fail if no snapshot file was created.
167     BuiltIn.Should_Contain    ${stdout}    /snapshots/    msg='Snapshot file was not created.'
168
169 Start_Newer_Odl
170     [Documentation]    Start the newer ODL on background.
171     [Tags]    1node    carpeople    # Not critical, to save space in default log.html presentation
172     ClusterManagement.Start_Members_From_List_Or_All    wait_for_sync=True    timeout=${CLUSTER_BOOTUP_SYNC_TIMEOUT}
173
174 Verify_Data_Is_Restored
175     [Documentation]    Wait until data check succeeds (there may be temporary 503).
176     BuiltIn.Wait_Until_Keyword_Succeeds    180s    5s    Check_Restored_Data
177
178 Archive_Older_Karaf_Log
179     [Documentation]    Only original location benefits from automatic karaf.log archivation.
180     SSHKeywords.Execute_Command_Should_Pass    xz -9evv ${alternative_bundlefolder}/data/log/karaf.log
181     SSHLibrary.Get_File    ${alternative_bundlefolder}/data/log/karaf.log.xz    older.karaf.log.xz
182     # TODO: Uncompress first (or last) megabyte for better readability?
183
184
185 *** Keywords ***
186 Setup_Suite
187     [Documentation]    Activate dependency Resources, create SSH connection, copy Python utility.
188     SetupUtils.Setup_Utils_For_Setup_And_Teardown
189     TemplatedRequests.Create_Default_Session
190     ${connection} =    SSHKeywords.Open_Connection_To_ODL_System
191     SSHLibrary.Put_File    ${CURDIR}/../../../../tools/odl-mdsal-clustering-tests/${PYTHON_UTILITY_FILENAME}
192
193 Check_Restored_Data
194     [Documentation]    Get car data from config datastore and check it is equal to the stored data.
195     ...    This has to be a separate keyword, as it is run under WUKS.
196     ${data_after} =    TemplatedRequests.Get_As_Json_Templated    folder=${CAR_VAR_DIR}    verify=False
197     BuiltIn.Should_Be_Equal    ${data_before}    ${data_after}
198
199 Extract_Karaf4_Boot_Features
200     [Documentation]    Extract boot features. It is used for the 1st line of karaf4 featuresBoot parameter from org.apache.karaf.features.cfg.
201     [Arguments]    ${csit_line}
202     ${bfeatures} =    String.Replace_String    ${csit_line}    ${Space}    ${Empty}
203     ${bfeatures} =    String.Replace_String    ${bfeatures}    featuresBoot=    ${Empty}
204     ${bfeatures} =    String.Replace_String    ${bfeatures}    ,\\    ${Empty}
205     RETURN    ${bfeatures}