Commit 218887adb0b074b5c4bcc5567d190e9c7a576ede
Merge pull request #133 from selurvedu/optimal_intrs
Optimal intervals
Showing
16 changed files
with
142 additions
and
64 deletions
| @@ -5,8 +5,7 @@ Suite Setup Test Suite Setup | @@ -5,8 +5,7 @@ Suite Setup Test Suite Setup | ||
| 5 | Suite Teardown Test Suite Teardown | 5 | Suite Teardown Test Suite Teardown |
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | -${role} viewer | ||
| 9 | -${broker} Quinta | 8 | +@{used_roles} tender_owner viewer |
| 10 | 9 | ||
| 11 | 10 | ||
| 12 | *** Test Cases *** | 11 | *** Test Cases *** |
| @@ -54,36 +54,80 @@ Set Suite Variable With Default Value | @@ -54,36 +54,80 @@ Set Suite Variable With Default Value | ||
| 54 | Завантажуємо дані про користувачів і майданчики | 54 | Завантажуємо дані про користувачів і майданчики |
| 55 | Log ${broker} | 55 | Log ${broker} |
| 56 | Log ${role} | 56 | Log ${role} |
| 57 | + # Suite variable; should be present in every test suite | ||
| 58 | + # in `*** Variables ***` section | ||
| 59 | + Log Many @{used_roles} | ||
| 57 | 60 | ||
| 61 | + # Load brokers data | ||
| 58 | ${file_path}= Get Variable Value ${BROKERS_FILE} brokers.yaml | 62 | ${file_path}= Get Variable Value ${BROKERS_FILE} brokers.yaml |
| 59 | - ${BROKERS}= load_initial_data_from ${file_path} | 63 | + ${BROKERS}= load_data_from ${file_path} mode=brokers |
| 60 | Log ${BROKERS} | 64 | Log ${BROKERS} |
| 61 | Set Suite Variable ${BROKERS} | 65 | Set Suite Variable ${BROKERS} |
| 66 | + # List of currently used brokers | ||
| 67 | + ${used_brokers}= Create List | ||
| 62 | 68 | ||
| 69 | + # Load users data | ||
| 63 | ${file_path}= Get Variable Value ${USERS_FILE} users.yaml | 70 | ${file_path}= Get Variable Value ${USERS_FILE} users.yaml |
| 64 | - ${USERS}= load_initial_data_from ${file_path} | ||
| 65 | - Set Global Variable ${USERS} | ||
| 66 | - | ||
| 67 | - Set Suite Variable With Default Value ${role} ${BROKERS['${broker}'].roles.${role}} | ||
| 68 | - Set Suite Variable With Default Value tender_owner Tender_Owner | ||
| 69 | - Set Suite Variable With Default Value provider Tender_User | ||
| 70 | - Set Suite Variable With Default Value provider1 Tender_User1 | ||
| 71 | - Set Suite Variable With Default Value viewer Tender_Viewer | ||
| 72 | - ${active_users}= Create Dictionary tender_owner=${tender_owner} provider=${provider} provider1=${provider1} viewer=${viewer} | ||
| 73 | - | ||
| 74 | - ${users_list}= Get Dictionary Items ${USERS.users} | ||
| 75 | - :FOR ${username} ${user_data} IN @{users_list} | ||
| 76 | - \ Log ${active_users} | ||
| 77 | - \ Log ${username} | 71 | + ${USERS}= load_data_from ${file_path} |
| 72 | + Log ${USERS.users} | ||
| 73 | + Set Suite Variable ${USERS} | ||
| 74 | + # List of currently used users | ||
| 75 | + ${used_users}= Create List | ||
| 76 | + | ||
| 77 | + # Handle `-v role:something` | ||
| 78 | + Run Keyword Unless '${role}' in @{used_roles} | ||
| 79 | + ... Log | ||
| 80 | + ... Role ${role} is not used in this test suite. | ||
| 81 | + ... WARN | ||
| 82 | + Set Suite Variable With Default Value | ||
| 83 | + ... ${role} | ||
| 84 | + ... ${BROKERS['${broker}'].roles.${role}} | ||
| 85 | + | ||
| 86 | + # Set default value for each role if it is not set yet; | ||
| 87 | + # fill `used_users`; | ||
| 88 | + # fill `used_brokers`. | ||
| 89 | + # | ||
| 90 | + # Don't even ask how this works! | ||
| 91 | + :FOR ${tmp_role} IN @{used_roles} | ||
| 92 | + \ Set Suite Variable With Default Value | ||
| 93 | + \ ... ${tmp_role} | ||
| 94 | + \ ... ${BROKERS['Quinta'].roles.${tmp_role}} | ||
| 95 | + \ Append To List ${used_users} ${${tmp_role}} | ||
| 96 | + \ Append To List ${used_brokers} ${USERS.users.${${tmp_role}}.broker} | ||
| 97 | + # Since `@{used_roles}` is already a suite variable, | ||
| 98 | + # let's make `@{used_brokers}` alike. | ||
| 99 | + ${used_brokers}= Remove Duplicates ${used_brokers} | ||
| 100 | + Set Suite Variable ${used_brokers} | ||
| 101 | + # We need to create two lists since Robot Framework doesn't support | ||
| 102 | + # dicts in `:FOR` loops. | ||
| 103 | + Log Many @{used_users} | ||
| 104 | + Log Many @{used_brokers} | ||
| 105 | + | ||
| 106 | + # A list of all users in users file | ||
| 107 | + ${known_users}= Get Dictionary Keys ${USERS.users} | ||
| 108 | + | ||
| 109 | + # Check whether users file contains an entry for each | ||
| 110 | + # selected user before preparing any clients | ||
| 111 | + :FOR ${username} IN @{used_users} | ||
| 112 | + \ List Should Contain Value | ||
| 113 | + \ ... ${known_users} | ||
| 114 | + \ ... ${username} | ||
| 115 | + \ ... msg=User ${username} not found in users file! | ||
| 116 | + | ||
| 117 | + # Prepare a client for each user | ||
| 118 | + :FOR ${username} IN @{used_users} | ||
| 78 | \ ${munch_dict}= munch_dict data=${True} | 119 | \ ${munch_dict}= munch_dict data=${True} |
| 79 | - \ Log Many ${munch_dict} | ||
| 80 | - \ ${status}= Run Keyword And Return Status Dictionary Should Contain Value ${active_users} ${username} | ||
| 81 | - \ ${keywords_file}= Get Broker Property By Username ${username} keywords_file | ||
| 82 | - \ Run Keyword If ${status} Завантажуємо бібліотеку з реалізацією для майданчика ${keywords_file} | ||
| 83 | - \ Run Keyword If ${status} Викликати для учасника ${username} Підготувати клієнт для користувача | ||
| 84 | - \ Run Keyword If ${status} Set To Dictionary ${USERS.users['${username}']} tender_data=${munch_dict} | 120 | + \ ${keywords_file}= Get Broker Property ${USERS.users.${username}.broker} keywords_file |
| 121 | + \ Завантажуємо бібліотеку з реалізацією для майданчика ${keywords_file} | ||
| 122 | + \ Run As ${username} Підготувати клієнт для користувача | ||
| 85 | \ ${LAST_REFRESH_DATE}= Get Current TZdate | 123 | \ ${LAST_REFRESH_DATE}= Get Current TZdate |
| 86 | - \ Set To Dictionary ${USERS.users['${username}']} LAST_REFRESH_DATE ${LAST_REFRESH_DATE} | 124 | + \ Set To Dictionary ${USERS} ${username}=${USERS.users.${username}} |
| 125 | + \ Set To Dictionary ${USERS.${username}} tender_data=${munch_dict} | ||
| 126 | + \ Set To Dictionary ${USERS.${username}} LAST_REFRESH_DATE ${LAST_REFRESH_DATE} | ||
| 127 | + | ||
| 128 | + # Drop all unused users | ||
| 129 | + Keep In Dictionary ${USERS.users} @{used_users} | ||
| 130 | + Log Many @{USERS} | ||
| 87 | 131 | ||
| 88 | 132 | ||
| 89 | Get Broker Property | 133 | Get Broker Property |
| @@ -92,11 +136,9 @@ Get Broker Property | @@ -92,11 +136,9 @@ Get Broker Property | ||
| 92 | ... This keyword returns a property of specified broker | 136 | ... This keyword returns a property of specified broker |
| 93 | ... if that property exists, otherwise, it returns a | 137 | ... if that property exists, otherwise, it returns a |
| 94 | ... default value. | 138 | ... default value. |
| 95 | - ${status}= Run Keyword And Return Status Should Contain ${BROKERS['${broker_name}']} ${property} | ||
| 96 | - Return From Keyword If ${status} ${BROKERS['${broker_name}'].${property}} | ||
| 97 | - # If broker doesn't have that property, fall back to default value | ||
| 98 | - Should Contain ${BROKERS['Default']} ${property} | ||
| 99 | - [return] ${BROKERS['Default'].${property}} | 139 | + Run Keyword If '${broker_name}'=='${None}' Fail \${broker_name} is NoneType |
| 140 | + Should Contain ${BROKERS['${broker_name}']} ${property} | ||
| 141 | + Return From Keyword ${BROKERS['${broker_name}'].${property}} | ||
| 100 | 142 | ||
| 101 | 143 | ||
| 102 | Get Broker Property By Username | 144 | Get Broker Property By Username |
| @@ -126,7 +168,7 @@ Get Broker Property By Username | @@ -126,7 +168,7 @@ Get Broker Property By Username | ||
| 126 | 168 | ||
| 127 | Завантажити дані про тендер | 169 | Завантажити дані про тендер |
| 128 | ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact.yaml | 170 | ${file_path}= Get Variable Value ${ARTIFACT_FILE} artifact.yaml |
| 129 | - ${ARTIFACT}= load_initial_data_from ${file_path} | 171 | + ${ARTIFACT}= load_data_from ${file_path} |
| 130 | Run Keyword If '${USERS.users['${tender_owner}'].broker}' == 'Quinta' | 172 | Run Keyword If '${USERS.users['${tender_owner}'].broker}' == 'Quinta' |
| 131 | ... Set To Dictionary ${USERS.users['${tender_owner}']} access_token=${ARTIFACT.access_token} | 173 | ... Set To Dictionary ${USERS.users['${tender_owner}']} access_token=${ARTIFACT.access_token} |
| 132 | ${TENDER}= Create Dictionary | 174 | ${TENDER}= Create Dictionary |
| @@ -137,9 +179,7 @@ Get Broker Property By Username | @@ -137,9 +179,7 @@ Get Broker Property By Username | ||
| 137 | 179 | ||
| 138 | 180 | ||
| 139 | Підготовка даних для створення тендера | 181 | Підготовка даних для створення тендера |
| 140 | - ${custom_intervals}= Get Broker Property By Username ${tender_owner} intervals | ||
| 141 | - ${default_intervals}= Get Broker Property Default intervals | ||
| 142 | - ${period_intervals}= merge_dicts ${default_intervals} ${custom_intervals} | 182 | + ${period_intervals}= compute_intrs ${BROKERS} ${used_brokers} |
| 143 | ${tender_data}= prepare_test_tender_data ${period_intervals} ${mode} | 183 | ${tender_data}= prepare_test_tender_data ${period_intervals} ${mode} |
| 144 | ${TENDER}= Create Dictionary | 184 | ${TENDER}= Create Dictionary |
| 145 | Set Global Variable ${TENDER} | 185 | Set Global Variable ${TENDER} |
| @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | ||
| 11 | 11 | ||
| 12 | *** Variables *** | 12 | *** Variables *** |
| 13 | ${mode} single | 13 | ${mode} single |
| 14 | +@{used_roles} tender_owner provider provider1 viewer | ||
| 14 | 15 | ||
| 15 | -${role} viewer | ||
| 16 | -${broker} Quinta | ||
| 17 | 16 | ||
| 18 | *** Test Cases *** | 17 | *** Test Cases *** |
| 19 | Можливість оголосити однопредметний тендер з неціновим показником | 18 | Можливість оголосити однопредметний тендер з неціновим показником |
| @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | ||
| 11 | 11 | ||
| 12 | *** Variables *** | 12 | *** Variables *** |
| 13 | ${mode} multi | 13 | ${mode} multi |
| 14 | +@{used_roles} tender_owner provider provider1 viewer | ||
| 14 | 15 | ||
| 15 | -${role} viewer | ||
| 16 | -${broker} Quinta | ||
| 17 | 16 | ||
| 18 | *** Test Cases *** | 17 | *** Test Cases *** |
| 19 | Можливість оголосити багатопредметний тендер | 18 | Можливість оголосити багатопредметний тендер |
| @@ -11,12 +11,10 @@ Suite Teardown Test Suite Teardown | @@ -11,12 +11,10 @@ Suite Teardown Test Suite Teardown | ||
| 11 | 11 | ||
| 12 | *** Variables *** | 12 | *** Variables *** |
| 13 | ${mode} multi | 13 | ${mode} multi |
| 14 | - | ||
| 15 | -${role} viewer | ||
| 16 | -${broker} Quinta | ||
| 17 | - | 14 | +@{used_roles} tender_owner provider provider1 viewer |
| 18 | ${complaint_id} 1 | 15 | ${complaint_id} 1 |
| 19 | 16 | ||
| 17 | + | ||
| 20 | *** Test Cases *** | 18 | *** Test Cases *** |
| 21 | Можливість оголосити мультилотовий тендер | 19 | Можливість оголосити мультилотовий тендер |
| 22 | [Tags] ${USERS.users['${tender_owner}'].broker}: Можливість оголосити мультилотовий тендер | 20 | [Tags] ${USERS.users['${tender_owner}'].broker}: Можливість оголосити мультилотовий тендер |
| @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | ||
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | ${mode} negotiation.quick | 8 | ${mode} negotiation.quick |
| 9 | -${role} viewer | ||
| 10 | -${broker} Quinta | 9 | +@{used_roles} tender_owner viewer |
| 11 | 10 | ||
| 12 | 11 | ||
| 13 | *** Test Cases *** | 12 | *** Test Cases *** |
| @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | ||
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | ${mode} negotiation | 8 | ${mode} negotiation |
| 9 | -${role} viewer | ||
| 10 | -${broker} Quinta | 9 | +@{used_roles} tender_owner viewer |
| 11 | 10 | ||
| 12 | 11 | ||
| 13 | *** Test Cases *** | 12 | *** Test Cases *** |
| @@ -6,9 +6,7 @@ Suite Teardown Test Suite Teardown | @@ -6,9 +6,7 @@ Suite Teardown Test Suite Teardown | ||
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | ${mode} openeu | 8 | ${mode} openeu |
| 9 | - | ||
| 10 | -${role} viewer | ||
| 11 | -${broker} Quinta | 9 | +@{used_roles} tender_owner provider provider1 viewer |
| 12 | 10 | ||
| 13 | 11 | ||
| 14 | *** Test Cases *** | 12 | *** Test Cases *** |
| @@ -6,9 +6,7 @@ Suite Teardown Test Suite Teardown | @@ -6,9 +6,7 @@ Suite Teardown Test Suite Teardown | ||
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | ${mode} openua | 8 | ${mode} openua |
| 9 | - | ||
| 10 | -${role} viewer | ||
| 11 | -${broker} Quinta | 9 | +@{used_roles} tender_owner provider provider1 viewer |
| 12 | 10 | ||
| 13 | 11 | ||
| 14 | *** Test Cases *** | 12 | *** Test Cases *** |
| @@ -5,8 +5,7 @@ Suite Setup Test Suite Setup | @@ -5,8 +5,7 @@ Suite Setup Test Suite Setup | ||
| 5 | Suite Teardown Test Suite Teardown | 5 | Suite Teardown Test Suite Teardown |
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | -${role} viewer | ||
| 9 | -${broker} Quinta | 8 | +@{used_roles} tender_owner viewer |
| 10 | 9 | ||
| 11 | 10 | ||
| 12 | *** Test Cases *** | 11 | *** Test Cases *** |
| @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | @@ -6,8 +6,7 @@ Suite Teardown Close all browsers | ||
| 6 | 6 | ||
| 7 | *** Variables *** | 7 | *** Variables *** |
| 8 | ${mode} reporting | 8 | ${mode} reporting |
| 9 | -${role} viewer | ||
| 10 | -${broker} Quinta | 9 | +@{used_roles} tender_owner viewer |
| 11 | 10 | ||
| 12 | 11 | ||
| 13 | *** Test Cases *** | 12 | *** Test Cases *** |
| @@ -142,14 +142,65 @@ def munch_to_object(data, format="yaml"): | @@ -142,14 +142,65 @@ def munch_to_object(data, format="yaml"): | ||
| 142 | return data.toYAML(allow_unicode=True, default_flow_style=False) | 142 | return data.toYAML(allow_unicode=True, default_flow_style=False) |
| 143 | 143 | ||
| 144 | 144 | ||
| 145 | -def load_initial_data_from(file_name): | 145 | +def load_data_from(file_name, mode=None): |
| 146 | if not os.path.exists(file_name): | 146 | if not os.path.exists(file_name): |
| 147 | file_name = os.path.join(os.path.dirname(__file__), 'data', file_name) | 147 | file_name = os.path.join(os.path.dirname(__file__), 'data', file_name) |
| 148 | with open(file_name) as file_obj: | 148 | with open(file_name) as file_obj: |
| 149 | if file_name.endswith(".json"): | 149 | if file_name.endswith(".json"): |
| 150 | - return Munch.fromDict(load(file_obj)) | 150 | + file_data = Munch.fromDict(load(file_obj)) |
| 151 | elif file_name.endswith(".yaml"): | 151 | elif file_name.endswith(".yaml"): |
| 152 | - return fromYAML(file_obj) | 152 | + file_data = fromYAML(file_obj) |
| 153 | + if mode == "brokers": | ||
| 154 | + default = file_data.pop('Default') | ||
| 155 | + brokers = {} | ||
| 156 | + for k, v in file_data.iteritems(): | ||
| 157 | + brokers[k] = merge_dicts(default, v) | ||
| 158 | + return brokers | ||
| 159 | + else: | ||
| 160 | + return file_data | ||
| 161 | + | ||
| 162 | + | ||
| 163 | +def compute_intrs(brokers_data, used_brokers): | ||
| 164 | + """Compute optimal values for period intervals. | ||
| 165 | + | ||
| 166 | + Notice: This function is maximally effective if ``brokers_data`` | ||
| 167 | + does not contain ``Default`` entry. | ||
| 168 | + Using `load_data_from` with ``mode='brokers'`` is recommended. | ||
| 169 | + """ | ||
| 170 | + num_types = (int, long, float) | ||
| 171 | + | ||
| 172 | + def recur(l, r): | ||
| 173 | + l, r = deepcopy(l), deepcopy(r) | ||
| 174 | + if isinstance(l, list) and isinstance(r, list) and len(l) == len(r): | ||
| 175 | + lst = [] | ||
| 176 | + for ll, rr in zip(l, r): | ||
| 177 | + lst.append(recur(ll, rr)) | ||
| 178 | + return lst | ||
| 179 | + elif isinstance(l, num_types) and isinstance(r, num_types): | ||
| 180 | + if l == r: | ||
| 181 | + return l | ||
| 182 | + if l > r: | ||
| 183 | + return l | ||
| 184 | + if l < r: | ||
| 185 | + return r | ||
| 186 | + elif isinstance(l, dict) and isinstance(r, dict): | ||
| 187 | + for k, v in r.iteritems(): | ||
| 188 | + if k not in l.keys(): | ||
| 189 | + l[k] = v | ||
| 190 | + else: | ||
| 191 | + l[k] = recur(l[k], v) | ||
| 192 | + return l | ||
| 193 | + else: | ||
| 194 | + raise TypeError("Couldn't recur({0}, {1})".format( | ||
| 195 | + str(type(l)), str(type(r)))) | ||
| 196 | + | ||
| 197 | + intrs = [] | ||
| 198 | + for i in used_brokers: | ||
| 199 | + intrs.append(brokers_data[i]['intervals']) | ||
| 200 | + result = intrs.pop(0) | ||
| 201 | + for i in intrs: | ||
| 202 | + result = recur(result, i) | ||
| 203 | + return result | ||
| 153 | 204 | ||
| 154 | 205 | ||
| 155 | def prepare_test_tender_data(procedure_intervals, mode): | 206 | def prepare_test_tender_data(procedure_intervals, mode): |
| @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | @@ -11,9 +11,8 @@ Suite Teardown Test Suite Teardown | ||
| 11 | 11 | ||
| 12 | *** Variables *** | 12 | *** Variables *** |
| 13 | ${mode} single | 13 | ${mode} single |
| 14 | +@{used_roles} tender_owner provider provider1 viewer | ||
| 14 | 15 | ||
| 15 | -${role} viewer | ||
| 16 | -${broker} Quinta | ||
| 17 | 16 | ||
| 18 | *** Test Cases *** | 17 | *** Test Cases *** |
| 19 | Можливість оголосити однопредметний тендер | 18 | Можливість оголосити однопредметний тендер |
| @@ -11,8 +11,8 @@ Suite Teardown Test Suite Teardown | @@ -11,8 +11,8 @@ Suite Teardown Test Suite Teardown | ||
| 11 | 11 | ||
| 12 | *** Variables *** | 12 | *** Variables *** |
| 13 | ${mode} single | 13 | ${mode} single |
| 14 | -${role} viewer | ||
| 15 | -${broker} Quinta | 14 | +@{used_roles} tender_owner provider viewer |
| 15 | + | ||
| 16 | 16 | ||
| 17 | *** Test Cases *** | 17 | *** Test Cases *** |
| 18 | Можливість оголосити однопредметний тендер | 18 | Можливість оголосити однопредметний тендер |
Please
register
or
login
to post a comment