Skip to content

Commit 3c9cbcd

Browse files
committed
work for 332
Add a R&R unit test Add a R&R integration test Introduce a new facility to run integration tests much like the examples
1 parent 020aba1 commit 3c9cbcd

File tree

3 files changed

+357
-0
lines changed

3 files changed

+357
-0
lines changed

test/test_integration.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# coding=utf-8
2+
3+
import os
4+
import watson_developer_cloud
5+
import pytest
6+
import sys
7+
from os import getcwd
8+
from subprocess import Popen, PIPE
9+
from os.path import join, dirname
10+
from glob import glob
11+
12+
# tests to exclude
13+
excludes = []
14+
15+
itests_path = join(dirname(__file__), '../', 'testintegration', '*.py')
16+
17+
# environment variables
18+
try:
19+
from dotenv import load_dotenv
20+
except:
21+
print('warning: dotenv module could not be imported')
22+
23+
try:
24+
dotenv_path = join(dirname(__file__), '../', '.env')
25+
load_dotenv(dotenv_path)
26+
except:
27+
print('warning: no .env file loaded')
28+
29+
30+
@pytest.mark.skipif(os.getenv('VCAP_SERVICES') is None, reason='requires VCAP_SERVICES')
31+
def test_integration():
32+
itests = glob(itests_path)
33+
for itest in itests:
34+
head, tail = os.path.split(itest)
35+
# exclude some tests cases like authorization
36+
if tail in excludes:
37+
continue
38+
39+
try:
40+
exec(open(itest).read(), globals())
41+
except Exception as e:
42+
assert False, 'itest in file ' + tail + ' failed with error: ' + str(e)
43+

test/test_retrieve_and_rank_v1.py

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import os
2+
import responses
3+
import watson_developer_cloud
4+
5+
@responses.activate
6+
def test_success():
7+
8+
# Ranker endpoints
9+
retrieve_and_rank = watson_developer_cloud.RetrieveAndRankV1(username="username",
10+
password="password")
11+
12+
listrank_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers'
13+
listrank_response = '{"rankers":[{"ranker_id":"3b140ax14-rank-10383","url":"https://gateway.watsonplatform.net/retrieve-and-rank' \
14+
'/api/v1/rankers/3b140ax14-rank-10383","name":"pythonRank","created":"2016-07-15T19:11:27.801Z"}]}'
15+
16+
responses.add(responses.GET, listrank_url,
17+
body=listrank_response, status=200,
18+
content_type='application/json')
19+
20+
retrieve_and_rank.list_rankers()
21+
22+
assert responses.calls[0].request.url == listrank_url
23+
assert responses.calls[0].response.text == listrank_response
24+
25+
statusrank_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers/3b140ax14-rank-10383'
26+
statusrank_response = '{"ranker_id":"3b140ax14-rank-10383","name":"pythonRank","created":"2016-07-15T19:11:27.801Z",' \
27+
'"url":"https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers/3b140ax14-rank-10383",' \
28+
'"status":"Available","status_description":"The ranker instance is now available and is ready to take ranker requests."}'
29+
30+
responses.add(responses.GET, statusrank_url,
31+
body=statusrank_response, status=200,
32+
content_type='application/json')
33+
34+
retrieve_and_rank.get_ranker_status('3b140ax14-rank-10383')
35+
36+
assert responses.calls[1].request.url == statusrank_url
37+
assert responses.calls[1].response.text == statusrank_response
38+
39+
rank_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers/3b140ax14-rank-10383/rank'
40+
rank_response = '{"ranker_id":"3b140ax14-rank-10383","url":"https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers/3b140ax14-rank-10383",' \
41+
'"top_answer":"30965a00-5415-4ef5-8e4a-bb21a7aeab44", "answers":[' \
42+
'{"answer_id":"30965a00-5415-4ef5-8e4a-bb21a7aeab44","score":180.0,"confidence":0.2636349925008873},' \
43+
'{"answer_id":"30965a00-5415-4ef5-8e4a-bb21a7aeab44","score":179.0,"confidence":0.262185794730098},' \
44+
'{"answer_id":"30965a00-5415-4ef5-8e4a-bb21a7aeab44","score":178.0,"confidence":0.25972667610243827}]}'
45+
46+
responses.add(responses.POST, rank_url,
47+
body=rank_response, status=200,
48+
content_type='application/json')
49+
50+
with open(os.path.join(os.path.dirname(__file__), '../resources/ranker_answer_data.csv'), 'rb') as answer_data:
51+
retrieve_and_rank.rank('3b140ax14-rank-10383', answer_data=answer_data, top_answers=3)
52+
53+
assert responses.calls[2].request.url == rank_url
54+
assert responses.calls[2].response.text == rank_response
55+
56+
createrank_url = listrank_url
57+
createrank_response = '{"ranker_id":"3b140ax14-rank-10544","name":"pythonRank","created":"2016-07-19T15:19:28.485Z",' \
58+
'"url":"https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/rankers/3b140ax14-rank-10544",' \
59+
'"status":"Training","status_description":"The ranker instance is in its training phase, not yet ready to accept rank requests"}'
60+
61+
responses.add(responses.POST, createrank_url,
62+
body=createrank_response, status=200,
63+
content_type='application/json')
64+
65+
with open(os.path.join(os.path.dirname(__file__), '../resources/ranker_training_data.csv'), 'rb') as training_data:
66+
retrieve_and_rank.create_ranker(training_data=training_data, name='pythonRank')
67+
68+
assert responses.calls[3].request.url == createrank_url
69+
assert responses.calls[3].response.text == createrank_response
70+
71+
removerank_url = statusrank_url
72+
removerank_response = '{}'
73+
74+
responses.add(responses.DELETE, removerank_url,
75+
body=removerank_response, status=200,
76+
content_type='application/json')
77+
78+
retrieve_and_rank.delete_ranker('3b140ax14-rank-10383')
79+
80+
assert responses.calls[4].request.url == removerank_url
81+
assert responses.calls[4].response.text == removerank_response
82+
83+
assert len(responses.calls) == 5
84+
85+
# Retrieve endpoints
86+
listcluster_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters'
87+
listcluster_response = '{"clusters":[{"solr_cluster_id":"sc0747112c_f978_4e1f_b97e_0e3a8101ac5b","cluster_name":"","cluster_size":"","solr_cluster_status":"READY"}]}'
88+
89+
responses.add(responses.GET, listcluster_url,
90+
body=listcluster_response, status=200,
91+
content_type='application/json')
92+
93+
retrieve_and_rank.list_solr_clusters()
94+
95+
assert responses.calls[5].request.url == listcluster_url
96+
assert responses.calls[5].response.text == listcluster_response
97+
98+
createcluster_url = listcluster_url
99+
createcluster_response = '{"solr_cluster_id":"sc0747112c_f978_4e1f_b97e_0e3a8101ac5b","cluster_name":"","cluster_size":"","solr_cluster_status":"NOT_AVAILABLE"}'
100+
101+
responses.add(responses.POST, createcluster_url,
102+
body=createcluster_response, status=200,
103+
content_type='application/json')
104+
105+
retrieve_and_rank.create_solr_cluster(cluster_name='pythonCluster', cluster_size=None)
106+
107+
assert responses.calls[6].request.url == createcluster_url
108+
assert responses.calls[6].response.text == createcluster_response
109+
110+
removecluster_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b'
111+
removecluster_response = '{"message":"WRRCSR023: Successfully deleted Solr cluster [sc0747112c_f978_4e1f_b97e_0e3a8101ac5b].","statusCode":200}'
112+
113+
responses.add(responses.DELETE, removecluster_url,
114+
body=removecluster_response, status=200,
115+
content_type='application/json')
116+
117+
retrieve_and_rank.delete_solr_cluster('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b')
118+
119+
assert responses.calls[7].request.url == removecluster_url
120+
assert responses.calls[7].response.text == removecluster_response
121+
122+
statuscluster_url = removecluster_url
123+
statuscluster_response = '{"solr_cluster_id":"scecb989cb_b204_4ebd_bc8d_c2244a499d8c","cluster_name":"","cluster_size":"","solr_cluster_status":"READY"}'
124+
125+
responses.add(responses.GET, statuscluster_url,
126+
body=statuscluster_response, status=200,
127+
content_type='application/json')
128+
129+
retrieve_and_rank.get_solr_cluster_status('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b')
130+
131+
assert responses.calls[8].request.url == statuscluster_url
132+
assert responses.calls[8].response.text == statuscluster_response
133+
134+
listconfigs_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/config'
135+
listconfigs_response = '{"solr_configs":[]}'
136+
137+
responses.add(responses.GET, listconfigs_url,
138+
body=listconfigs_response, status=200,
139+
content_type='application/json')
140+
141+
retrieve_and_rank.list_configs('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b')
142+
143+
assert responses.calls[9].request.url == listconfigs_url
144+
assert responses.calls[9].response.text == listconfigs_response
145+
146+
createconfig_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/config/exampleconfig'
147+
createconfig_response = '{"message":"WRRCSR026: Successfully uploaded named config [example-config] for Solr cluster [sc0747112c_f978_4e1f_b97e_0e3a8101ac5b].","statusCode":200}'
148+
149+
responses.add(responses.POST, createconfig_url,
150+
body=createconfig_response, status=200,
151+
content_type='application/json')
152+
153+
with open(os.path.join(os.path.dirname(__file__), '../resources/solr_config.zip'), 'rb') as config_data:
154+
retrieve_and_rank.create_config('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'exampleconfig', config=config_data)
155+
156+
assert responses.calls[10].request.url == createconfig_url
157+
assert responses.calls[10].response.text == createconfig_response
158+
159+
removeconfig_url = createconfig_url
160+
removeconfig_response = '{"message":"WRRCSR025: Successfully deleted named config [example-config] for Solr cluster [sc0747112c_f978_4e1f_b97e_0e3a8101ac5b]].","statusCode":200}'
161+
162+
responses.add(responses.DELETE, removeconfig_url,
163+
body=removeconfig_response, status=200,
164+
content_type='application/json')
165+
166+
retrieve_and_rank.delete_config('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'exampleconfig')
167+
168+
assert responses.calls[11].request.url == removeconfig_url
169+
assert responses.calls[11].response.text == removeconfig_response
170+
171+
getconfig_url = createconfig_url
172+
getconfig_response = '% Total % Received % Xferd Average Speed Time Time Time Current' \
173+
' Dload Upload Total Spent Left Speed' \
174+
'100 864 0 864 0 0 1627 0 --:--:-- --:--:-- --:--:-- 1627'
175+
176+
responses.add(responses.GET, getconfig_url,
177+
body=getconfig_response, status=200,
178+
content_type='application/json')
179+
180+
retrieve_and_rank.get_config('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'exampleconfig')
181+
182+
assert responses.calls[12].request.url == getconfig_url
183+
assert responses.calls[12].response.text == getconfig_response
184+
185+
listcollection_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/solr/admin/collections'
186+
listcollection1_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/solr/admin/collections?wt=json&action=LIST'
187+
listcollection_response = '{"responseHeader":{"status":0,"QTime":0},"collections":["examplecollection"]}'
188+
189+
responses.add(responses.GET, listcollection_url,
190+
body=listcollection_response, status=200,
191+
content_type='application/json')
192+
193+
retrieve_and_rank.list_collections('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b')
194+
195+
# the response url changes every time the test is run
196+
# assert responses.calls[13].request.url == listcollection1_url
197+
assert responses.calls[13].response.text == listcollection_response
198+
199+
createcollection_url = listcollection_url
200+
createcollection1_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/solr/admin/collections?name=examplecollection&collection.configName=exampleconfig&wt=json&action=CREATE'
201+
createcollection_response = '{}'
202+
203+
responses.add(responses.POST, createcollection_url,
204+
body=createcollection_response, status=200,
205+
content_type='application/json')
206+
207+
retrieve_and_rank.create_collection('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'examplecollection', 'exampleconfig')
208+
209+
# assert responses.calls[14].request.url == createcollection1_url
210+
assert responses.calls[14].response.text == createcollection_response
211+
212+
deletecollection_url = listcollection_url
213+
deletecollection1_url = 'https://gateway.watsonplatform.net/retrieve-and-rank/api/v1/solr_clusters/sc0747112c_f978_4e1f_b97e_0e3a8101ac5b/solr/admin/collections?wt=json&name=examplecollection&action=DELETE'
214+
deletecollection_response = '{}'
215+
216+
responses.add(responses.POST, deletecollection_url,
217+
body=deletecollection_response, status=200,
218+
content_type='application/json')
219+
220+
retrieve_and_rank.delete_collection('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'examplecollection', 'exampleconfig')
221+
222+
# assert responses.calls[15].request.url == deletecollection1_url
223+
assert responses.calls[15].response.text == deletecollection_response
224+
225+
retrieve_and_rank.get_pysolr_client('sc0747112c_f978_4e1f_b97e_0e3a8101ac5b', 'examplecollection')
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import json
2+
import os
3+
import time
4+
import sys
5+
from watson_developer_cloud import RetrieveAndRankV1
6+
7+
8+
retrieve_and_rank = RetrieveAndRankV1(
9+
username='YOUR SERVICE USERNAME',
10+
password='YOUR SERVICE PASSWORD')
11+
12+
# End to End integration retrieve test
13+
mycluster = retrieve_and_rank.create_solr_cluster(cluster_name='Python Test Cluster', cluster_size=None)
14+
print(json.dumps(mycluster, indent=2))
15+
16+
retrieve_results = retrieve_and_rank.list_solr_clusters()
17+
print(json.dumps(retrieve_results, indent=2))
18+
19+
retrieve_status = retrieve_and_rank.get_solr_cluster_status(solr_cluster_id=mycluster['solr_cluster_id'])
20+
print(json.dumps(retrieve_status, indent=2))
21+
22+
# 10 minutes should be plenty for a cluster to complete
23+
trainingtimeout = time.time() + 60 * 10
24+
print ('Waiting for Cluster to become available!')
25+
while retrieve_status['solr_cluster_status'] != "READY":
26+
time.sleep(5)
27+
if time.time() > trainingtimeout:
28+
print ('Cluster creation failed!')
29+
retrieve_results = retrieve_and_rank.delete_solr_cluster(mycluster['solr_cluster_id'])
30+
sys.exit(1)
31+
retrieve_status = retrieve_and_rank.get_solr_cluster_status(solr_cluster_id=mycluster['solr_cluster_id'])
32+
33+
with open(os.path.join(os.path.dirname(__file__), '../resources/solr_config.zip'), 'rb') as config:
34+
retrieve_results = retrieve_and_rank.create_config(mycluster['solr_cluster_id'], 'python-test-config', config)
35+
print(json.dumps(retrieve_results, indent=2))
36+
37+
retrieve_results = retrieve_and_rank.list_configs(solr_cluster_id=mycluster['solr_cluster_id'])
38+
print(json.dumps(retrieve_results, indent=2))
39+
40+
retrieve_results = retrieve_and_rank.get_config(mycluster['solr_cluster_id'], 'python-test-config')
41+
print(retrieve_results)
42+
43+
retrieve_results = retrieve_and_rank.create_collection(mycluster['solr_cluster_id'], 'python-test-collection', 'python-test-config')
44+
print(json.dumps(retrieve_results, indent=2))
45+
46+
retrieve_results = retrieve_and_rank.list_collections(solr_cluster_id=mycluster['solr_cluster_id'])
47+
print(json.dumps(retrieve_results, indent=2))
48+
49+
pysolr_client = retrieve_and_rank.get_pysolr_client(mycluster['solr_cluster_id'], 'python-test-collection')
50+
query_results = pysolr_client.search('bananas')
51+
print('{0} documents found'.format(len(query_results.docs)))
52+
53+
retrieve_results = retrieve_and_rank.delete_collection(mycluster['solr_cluster_id'], 'python-test-collection', 'python-test-config')
54+
print(json.dumps(retrieve_results, indent=2))
55+
56+
retrieve_results = retrieve_and_rank.delete_config(mycluster['solr_cluster_id'], 'python-test-config')
57+
print(json.dumps(retrieve_results, indent=2))
58+
59+
retrieve_results = retrieve_and_rank.delete_solr_cluster(mycluster['solr_cluster_id'])
60+
print(json.dumps(retrieve_results, indent=2))
61+
62+
# End to End integration ranker test
63+
with open(os.path.join(os.path.dirname(__file__), '../resources/ranker_training_data.csv'), 'rb') as training_data:
64+
myranker = retrieve_and_rank.create_ranker(training_data=training_data, name='Python Test Ranker')
65+
print(json.dumps(myranker, indent=2))
66+
67+
ranker_results = retrieve_and_rank.list_rankers()
68+
print(json.dumps(ranker_results, indent=2))
69+
70+
ranker_status = retrieve_and_rank.get_ranker_status(myranker['ranker_id'])
71+
print(json.dumps(ranker_status, indent=2))
72+
73+
# 10 minutes should be plenty for a train to complete
74+
trainingtimeout = time.time() + 60 * 10
75+
print ('Waiting for Ranker to become available!')
76+
while ranker_status['status'] != "Available":
77+
time.sleep(5)
78+
if time.time() > trainingtimeout:
79+
print ('Ranker Training failed!')
80+
ranker_results = retrieve_and_rank.delete_ranker(myranker['ranker_id'])
81+
sys.exit(1)
82+
ranker_status = retrieve_and_rank.get_ranker_status(myranker['ranker_id'])
83+
84+
with open(os.path.join(os.path.dirname(__file__), '../resources/ranker_answer_data.csv'), 'rb') as answer_data:
85+
ranker_results = retrieve_and_rank.rank(myranker['ranker_id'], answer_data)
86+
print(json.dumps(ranker_results, indent=2))
87+
88+
ranker_results = retrieve_and_rank.delete_ranker(myranker['ranker_id'])
89+
print(json.dumps(ranker_results))

0 commit comments

Comments
 (0)