Commit 218887adb0b074b5c4bcc5567d190e9c7a576ede

Authored by selurvedu
2 parents 61e4e8b2 b9020598

Merge pull request #133 from selurvedu/optimal_intrs

Optimal intervals
@@ -6,8 +6,7 @@ Suite Teardown Test Suite Teardown @@ -6,8 +6,7 @@ Suite Teardown Test Suite Teardown
6 6
7 7
8 *** Variables *** 8 *** Variables ***
9 -${role} viewer  
10 -${broker} Quinta 9 +@{used_roles} viewer
11 10
12 11
13 *** 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 ***
@@ -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 ***
1 *** Variables *** 1 *** Variables ***
2 ${api_host_url} https://lb.api-sandbox.openprocurement.org 2 ${api_host_url} https://lb.api-sandbox.openprocurement.org
3 ${api_version} 0.12 3 ${api_version} 0.12
  4 +${broker} Quinta
  5 +${role} viewer
@@ -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