Skip to content

Commit 82adab5

Browse files
committed
Split test_proxy, rename others according to modules
1 parent c9ae42a commit 82adab5

File tree

11 files changed

+370
-349
lines changed

11 files changed

+370
-349
lines changed

tests/client/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
TEST_HS_ENDPOINT = os.getenv('HS_ENDPOINT',
2323
'http://storage.vm.scrapinghub.com')
2424

25+
# use some fixed timestamp to represent current time
26+
TEST_TS = 1476803148638
27+
2528
# vcrpy creates the cassetes automatically under VCR_CASSETES_DIR
2629
VCR_CASSETES_DIR = 'tests/client/cassetes'
2730

tests/client/test_activity.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import types
2+
3+
import pytest
4+
5+
from .conftest import TEST_PROJECT_ID
6+
7+
8+
def _add_test_activity(project):
9+
activity = project.activity
10+
jobkey = TEST_PROJECT_ID + '/2/3'
11+
events = [{'event': 'job:completed', 'job': jobkey, 'user': 'jobrunner'},
12+
{'event': 'job:cancelled', 'job': jobkey, 'user': 'john'}]
13+
activity.add(events)
14+
15+
16+
def test_activity_wrong_project(project):
17+
event = {'event': 'job:completed', 'job': '123/1/1', 'user': 'user'}
18+
with pytest.raises(ValueError):
19+
project.activity.add(event)
20+
21+
22+
def test_activity_iter(project):
23+
_add_test_activity(project)
24+
activity = project.activity.iter()
25+
assert isinstance(activity, types.GeneratorType)
26+
activity_item = next(activity)
27+
assert activity_item == {'event': 'job:cancelled',
28+
'job': TEST_PROJECT_ID + '/2/3',
29+
'user': 'john'}
30+
31+
32+
def test_activity_list(project):
33+
_add_test_activity(project)
34+
activity = project.activity.list(count=2)
35+
assert isinstance(activity, list)
36+
assert len(activity) == 2
37+
assert activity[0] == {'event': 'job:cancelled',
38+
'job': TEST_PROJECT_ID + '/2/3',
39+
'user': 'john'}
40+
assert activity[1] == {'event': 'job:completed',
41+
'job': TEST_PROJECT_ID + '/2/3',
42+
'user': 'jobrunner'}

tests/client/test_client.py

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
from scrapinghub.client.jobs import Job
66
from scrapinghub.client.projects import Projects, Project
77

8-
from scrapinghub.hubstorage.utils import apipoll
9-
10-
from .conftest import TEST_PROJECT_ID, TEST_SPIDER_NAME
11-
from .conftest import TEST_USER_AUTH, TEST_DASH_ENDPOINT
8+
from .conftest import TEST_PROJECT_ID
129

1310

1411
# ScrapinghubClient class tests
@@ -33,41 +30,3 @@ def test_client_get_project(client):
3330
def test_client_get_job(client):
3431
fake_job = client.get_job('1/2/3')
3532
assert isinstance(fake_job, Job)
36-
37-
38-
# Projects class tests
39-
40-
41-
def test_client_projects_get_project(client):
42-
projects = client.projects
43-
# testing with int project id
44-
p1 = projects.get(int(TEST_PROJECT_ID))
45-
assert isinstance(p1, Project)
46-
# testing with string project id
47-
p2 = projects.get(TEST_PROJECT_ID)
48-
assert isinstance(p2, Project)
49-
assert p1.key == p2.key
50-
51-
52-
def test_client_projects_list_projects(client):
53-
projects = client.projects.list()
54-
assert client.projects.list() == []
55-
56-
# use user apikey to list test projects
57-
client = ScrapinghubClient(TEST_USER_AUTH, TEST_DASH_ENDPOINT)
58-
projects = client.projects.list()
59-
assert isinstance(projects, list)
60-
assert int(TEST_PROJECT_ID) in projects
61-
62-
63-
def test_client_projects_summary(client, project):
64-
# add at least one running or pending job to ensure summary is returned
65-
project.jobs.schedule(TEST_SPIDER_NAME, meta={'state': 'running'})
66-
67-
def _get_summary():
68-
summaries = {str(js['project']): js
69-
for js in client.projects.summary()}
70-
return summaries.get(TEST_PROJECT_ID)
71-
72-
summary = apipoll(_get_summary)
73-
assert summary is not None

tests/client/test_items.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
3+
import pytest
4+
from six.moves import range
5+
6+
from scrapinghub.hubstorage.serialization import mpdecode
7+
8+
9+
def _add_test_items(job):
10+
for i in range(3):
11+
job.items.write({'id': i, 'data': 'data' + str(i)})
12+
job.items.flush()
13+
job.items.close()
14+
15+
16+
def test_items_iter(spider):
17+
job = spider.jobs.schedule(meta={'state': 'running'})
18+
_add_test_items(job)
19+
20+
o = job.items.iter()
21+
assert next(o) == {'id': 0, 'data': 'data0'}
22+
assert next(o) == {'id': 1, 'data': 'data1'}
23+
next(o)
24+
with pytest.raises(StopIteration):
25+
next(o)
26+
27+
o = job.items.iter(offset=2)
28+
assert next(o) == {'id': 2, 'data': 'data2'}
29+
with pytest.raises(StopIteration):
30+
next(o)
31+
32+
o = job.items.iter_raw_json(offset=2)
33+
item = json.loads(next(o))
34+
assert item['id'] == 2
35+
assert item['data'] == 'data2'
36+
with pytest.raises(StopIteration):
37+
next(o)
38+
39+
msgpacked_o = job.items.iter_raw_msgpack(offset=2)
40+
o = mpdecode(msgpacked_o)
41+
assert item['id'] == 2
42+
assert item['data'] == 'data2'
43+
44+
45+
def test_items_list(spider):
46+
job = spider.jobs.schedule(meta={'state': 'running'})
47+
_add_test_items(job)
48+
49+
o = job.items.list()
50+
assert isinstance(o, list)
51+
assert len(o) == 3
52+
assert o[0] == {'id': 0, 'data': 'data0'}
53+
assert o[1] == {'id': 1, 'data': 'data1'}
54+
assert o[2] == {'id': 2, 'data': 'data2'}

tests/client/test_logs.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import json
2+
import types
3+
from numbers import Integral
4+
5+
import pytest
6+
7+
from scrapinghub.client.utils import LogLevel
8+
from scrapinghub.hubstorage.serialization import mpdecode
9+
10+
from .conftest import TEST_TS
11+
12+
13+
def _add_test_logs(job):
14+
job.logs.log('simple-msg1')
15+
job.logs.log('simple-msg2', ts=TEST_TS)
16+
job.logs.log('simple-msg3', level=LogLevel.DEBUG)
17+
18+
job.logs.debug('debug-msg')
19+
job.logs.info('info-msg')
20+
job.logs.warning('warning-msg')
21+
job.logs.warn('warn-msg')
22+
job.logs.error('error-msg')
23+
24+
# test raw write interface
25+
job.logs.write({'message': 'test',
26+
'level': LogLevel.INFO,
27+
'time': TEST_TS})
28+
job.logs.flush()
29+
30+
31+
def test_logs_base(spider):
32+
job = spider.jobs.schedule()
33+
assert list(job.logs.iter()) == []
34+
assert job.logs.batch_write_start() == 0
35+
_add_test_logs(job)
36+
log1 = job.logs.get(0)
37+
assert log1['level'] == 20
38+
assert log1['message'] == 'simple-msg1'
39+
assert isinstance(log1['time'], Integral) and log1['time'] > 0
40+
assert job.logs.stats() == {
41+
'counts': {'10': 2, '20': 4, '30': 2, '40': 1},
42+
'totals': {'input_bytes': 91, 'input_values': 9}
43+
}
44+
job.logs.close()
45+
46+
47+
def test_logs_iter(spider):
48+
job = spider.jobs.schedule()
49+
_add_test_logs(job)
50+
51+
logs1 = job.logs.iter()
52+
assert isinstance(logs1, types.GeneratorType)
53+
assert next(logs1).get('message') == 'simple-msg1'
54+
assert next(logs1).get('message') == 'simple-msg2'
55+
assert next(logs1).get('message') == 'simple-msg3'
56+
57+
# testing offset
58+
logs2 = job.logs.iter(offset=3)
59+
assert next(logs2).get('message') == 'debug-msg'
60+
assert next(logs2).get('message') == 'info-msg'
61+
62+
# testing level
63+
logs3 = job.logs.iter(level='ERROR')
64+
assert next(logs3).get('message') == 'error-msg'
65+
with pytest.raises(StopIteration):
66+
next(logs3).get('message')
67+
68+
69+
def test_logs_list(spider):
70+
job = spider.jobs.schedule()
71+
_add_test_logs(job)
72+
73+
logs1 = job.logs.list()
74+
assert isinstance(logs1, list)
75+
assert len(logs1) == 9
76+
assert logs1[0].get('message') == 'simple-msg1'
77+
assert logs1[1].get('message') == 'simple-msg2'
78+
assert logs1[2].get('message') == 'simple-msg3'
79+
80+
# testing offset
81+
logs2 = job.logs.list(offset=3)
82+
assert len(logs2) == 6
83+
assert logs2[0].get('message') == 'debug-msg'
84+
assert logs2[1].get('message') == 'info-msg'
85+
86+
# testing level
87+
logs3 = job.logs.list(level='ERROR')
88+
assert len(logs3) == 1
89+
assert logs3[0].get('message') == 'error-msg'
90+
91+
92+
def test_logs_list_filter(spider):
93+
job = spider.jobs.schedule()
94+
_add_test_logs(job)
95+
96+
logs1 = job.logs.list(filter='["message", "contains", ["simple"]]')
97+
assert isinstance(logs1, list)
98+
assert len(logs1) == 3
99+
assert logs1[0].get('message') == 'simple-msg1'
100+
101+
logs2 = job.logs.list(filter=[['message', 'contains', ['simple']]])
102+
assert len(logs2) == 3
103+
104+
logs3 = job.logs.list(filter=[('message', 'contains', ['simple'])])
105+
assert len(logs3) == 3
106+
107+
108+
def test_logs_iter_raw_json(spider):
109+
job = spider.jobs.schedule()
110+
_add_test_logs(job)
111+
112+
logs0 = job.logs.iter_raw_json(offset=2)
113+
raw_log0 = next(logs0)
114+
log0 = json.loads(raw_log0)
115+
assert log0.get('message') == 'simple-msg3'
116+
assert log0.get('_key')
117+
assert isinstance(log0.get('time'), Integral)
118+
assert log0.get('level') == 10
119+
120+
logs1 = job.logs.iter_raw_json(level='ERROR')
121+
raw_log1 = next(logs1)
122+
log1 = json.loads(raw_log1)
123+
assert log1.get('message') == 'error-msg'
124+
125+
126+
def test_logs_iter_raw_msgpack(spider):
127+
job = spider.jobs.schedule()
128+
_add_test_logs(job)
129+
130+
logs1 = job.logs.iter_raw_msgpack(offset=2)
131+
assert isinstance(logs1, types.GeneratorType)
132+
unpacked_logs1 = list(mpdecode(logs1))
133+
assert unpacked_logs1[0].get('message') == 'simple-msg3'
134+
135+
logs2 = job.logs.iter_raw_msgpack(level='ERROR')
136+
unpacked_logs2 = list(mpdecode(logs2))
137+
assert unpacked_logs2[0].get('message') == 'error-msg'
Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,62 @@
44
import pytest
55
from six.moves import range
66

7+
from scrapinghub import ScrapinghubClient
78
from scrapinghub.client.activity import Activity
89
from scrapinghub.client.collections import Collections
910
from scrapinghub.client.exceptions import DuplicateJobError
1011
from scrapinghub.client.frontiers import Frontiers
1112
from scrapinghub.client.jobs import Jobs, Job
12-
from scrapinghub.client.projects import Settings
13+
from scrapinghub.client.projects import Project, Settings
1314
from scrapinghub.client.spiders import Spiders
1415

16+
from scrapinghub.hubstorage.utils import apipoll
17+
1518
from .conftest import TEST_PROJECT_ID, TEST_SPIDER_NAME
19+
from .conftest import TEST_USER_AUTH, TEST_DASH_ENDPOINT
1620
from .utils import validate_default_meta
1721

1822

23+
# Projects class tests
24+
25+
26+
def test_client_projects_get_project(client):
27+
projects = client.projects
28+
# testing with int project id
29+
p1 = projects.get(int(TEST_PROJECT_ID))
30+
assert isinstance(p1, Project)
31+
# testing with string project id
32+
p2 = projects.get(TEST_PROJECT_ID)
33+
assert isinstance(p2, Project)
34+
assert p1.key == p2.key
35+
36+
37+
def test_client_projects_list_projects(client):
38+
projects = client.projects.list()
39+
assert client.projects.list() == []
40+
41+
# use user apikey to list test projects
42+
client = ScrapinghubClient(TEST_USER_AUTH, TEST_DASH_ENDPOINT)
43+
projects = client.projects.list()
44+
assert isinstance(projects, list)
45+
assert int(TEST_PROJECT_ID) in projects
46+
47+
48+
def test_client_projects_summary(client, project):
49+
# add at least one running or pending job to ensure summary is returned
50+
project.jobs.schedule(TEST_SPIDER_NAME, meta={'state': 'running'})
51+
52+
def _get_summary():
53+
summaries = {str(js['project']): js
54+
for js in client.projects.summary()}
55+
return summaries.get(TEST_PROJECT_ID)
56+
57+
summary = apipoll(_get_summary)
58+
assert summary is not None
59+
60+
61+
# Project class tests
62+
1963
def test_project_subresources(project):
2064
assert project.key == TEST_PROJECT_ID
2165
assert isinstance(project.collections, Collections)

0 commit comments

Comments
 (0)