Completed
Push — master ( d57b0b...80936f )
by
unknown
01:57
created

StatisticsTest.test_parse_hw()   A

Complexity

Conditions 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
# coding: utf8
2
3
"""
4
This software is licensed under the Apache 2 license, quoted below.
5
6
Copyright 2014 Crystalnix Limited
7
8
Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
use this file except in compliance with the License. You may obtain a copy of
10
the License at
11
12
    http://www.apache.org/licenses/LICENSE-2.0
13
14
Unless required by applicable law or agreed to in writing, software
15
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
License for the specific language governing permissions and limitations under
18
the License.
19
"""
20
21
from builtins import range
22
23
from datetime import datetime
24
from uuid import UUID
25
26
from django.test import TestCase
27
from django.core.files.uploadedfile import SimpleUploadedFile
28
29
from mock import patch
30
from freezegun import freeze_time
31
from bitmapist import DayEvents, HourEvents, mark_event
32
33
from omaha.tests import fixtures
34
from omaha.parser import parse_request
35
from omaha.statistics import (
36
    userid_counting,
37
    add_app_statistics,
38
    add_app_live_statistics,
39
    is_user_active,
40
    get_kwargs_for_model,
41
    parse_os,
42
    parse_hw,
43
    parse_req,
44
    parse_apps,
45
    parse_events,
46
    collect_statistics,
47
    update_live_statistics,
48
    get_users_statistics_months,
49
    get_channel_statistics,
50
    get_users_versions,
51
)
52
53
from omaha.tests.utils import temporary_media_root, create_app_xml
54
from omaha.utils import redis, get_id
55
from omaha.settings import DEFAULT_CHANNEL
56
from omaha.models import (
57
    ACTIVE_USERS_DICT_CHOICES,
58
    Os,
59
    Hw,
60
    Request,
61
    AppRequest,
62
    Event,
63
    Application,
64
    Platform,
65
    Channel,
66
    Version,
67
)
68
from sparkle.models import SparkleVersion
69
from sparkle.statistics import userid_counting as mac_userid_counting
70
71
72
class StatisticsTest(TestCase):
73
    def setUp(self):
74
        redis.flushdb()
75
76
    def tearDown(self):
77
        redis.flushdb()
78
79
    @patch('omaha.statistics.add_app_statistics')
80
    def test_userid_counting(self, mock_add_app_statistics):
81
        now = datetime.utcnow()
82
83
        userid1 = '{F07B3878-CD6F-4B96-B52F-95C4D23077E0}'
84
        user1_id = get_id(userid1)
85
86
        userid2 = '{EC4C5647-F798-4BCA-83DA-926CD448A1D5}'
87
        user2_id = get_id(userid2)
88
89
        app_list = [dict(appid='{F97917B1-19AB-48C1-9802-CEF305B10804}'),
90
                    dict(appid='{555B8D18-076D-4576-9579-1FD7F0399EAE}')]
91
92
        request_events = DayEvents('request', now.year, now.month, now.day)
93
94
        self.assertFalse(user1_id in request_events)
95
        self.assertEqual(len(request_events), 0)
96
97
        userid_counting(userid1, app_list, 'win')
98
99
        for app in app_list:
100
            mock_add_app_statistics.assert_any_call(user1_id, 'win', app, now=None)
101
102
        self.assertEqual(len(request_events), 1)
103
        self.assertTrue(user1_id in request_events)
104
105
        userid_counting(userid1, app_list, 'win')
106
107
        for app in app_list:
108
            mock_add_app_statistics.assert_any_call(user1_id, 'win', app, now=None)
109
110
        self.assertEqual(len(request_events), 1)
111
112
        self.assertFalse(user2_id in request_events)
113
        userid_counting(userid2, app_list[:1], 'win')
114
        self.assertTrue(user2_id in request_events)
115
        for app in app_list[:1]:
116
            mock_add_app_statistics.assert_any_call(user2_id, 'win', app, now=None)
117
118
        self.assertEqual(len(request_events), 2)
119
120
    @freeze_time('2016-1-1')
121
    def test_add_app_statistics(self):
122
        now = datetime.utcnow()
123
        next_month = now.replace(month=now.month + 1)
124
        userid = 1
125
        channel = DEFAULT_CHANNEL
126
        platform = 'win'
127
        app_kwargs = dict(appid='{F97917B1-20AB-48C1-9802-CEF305B10804}', version='30.0.123.1234')
128
        success_app = create_app_xml(events=fixtures.event_install_success, **app_kwargs)
129
        error_app = create_app_xml(events=fixtures.event_install_error, **app_kwargs)
130
        appid = app_kwargs.get('appid')
131
        version = app_kwargs.get('version')
132
133
        events_request_appid = lambda date=now: DayEvents.from_date('request:%s' % appid, date)
134
        events_new_appid = lambda date=now: DayEvents.from_date('new_install:%s' % appid, date)
135
        events_request_appid_version = lambda date=now: DayEvents.from_date('request:{}:{}'.format(appid, version), date)
136
        events_request_appid_platform = lambda date=now: DayEvents.from_date('request:{}:{}'.format(appid, platform), date)
137
        events_new_appid_platform = lambda date=now: DayEvents.from_date('new_install:{}:{}'.format(appid, platform), date)
138
        events_request_appid_channel = lambda date=now: DayEvents.from_date('request:{}:{}'.format(appid, channel), date)
139
        events_request_appid_platform_version = lambda date=now: DayEvents.from_date('request:{}:{}:{}'.format(appid, platform, version), date)
140
141
142
        self.assertEqual(len(events_new_appid()), 0)
143
        self.assertEqual(len(events_request_appid()), 0)
144
        self.assertEqual(len(events_request_appid_version()), 0)
145
        self.assertEqual(len(events_request_appid_platform()), 0)
146
        self.assertEqual(len(events_new_appid_platform()), 0)
147
        self.assertEqual(len(events_request_appid_channel()), 0)
148
        self.assertEqual(len(events_request_appid_platform_version()), 0)
149
150
        add_app_statistics(userid, platform, error_app)
151
152
        self.assertEqual(len(events_new_appid()), 0)
153
        self.assertEqual(len(events_request_appid()), 0)
154 View Code Duplication
        self.assertEqual(len(events_request_appid_version()), 0)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
155
        self.assertEqual(len(events_request_appid_platform()), 0)
156
        self.assertEqual(len(events_new_appid_platform()), 0)
157
        self.assertEqual(len(events_request_appid_channel()), 0)
158
        self.assertEqual(len(events_request_appid_platform_version()), 0)
159
160
        add_app_statistics(userid, platform, success_app)
161
        self.assertEqual(len(events_new_appid()), 1)
162
        self.assertEqual(len(events_request_appid()), 0)
163
        self.assertEqual(len(events_request_appid_version()), 1)
164
        self.assertEqual(len(events_new_appid_platform()), 1)
165
        self.assertEqual(len(events_request_appid_platform()), 0)
166
        self.assertEqual(len(events_request_appid_channel()), 1)
167
        self.assertEqual(len(events_request_appid_platform_version()), 1)
168
169
        self.assertIn(userid, events_new_appid())
170
        self.assertIn(userid, events_request_appid_version())
171
        self.assertIn(userid, events_new_appid_platform())
172
        self.assertIn(userid, events_request_appid_channel())
173
        self.assertIn(userid, events_request_appid_platform_version())
174
175
        add_app_statistics(userid, platform, success_app)
176
        self.assertEqual(len(events_new_appid()), 1)
177
        self.assertEqual(len(events_request_appid()), 0)
178
        self.assertEqual(len(events_request_appid_version()), 1)
179
        self.assertEqual(len(events_new_appid_platform()), 1)
180
        self.assertEqual(len(events_request_appid_platform()), 0)
181
        self.assertEqual(len(events_request_appid_channel()), 1)
182
        self.assertEqual(len(events_request_appid_platform_version()), 1)
183
184
        with freeze_time(next_month):
185
            add_app_statistics(userid, platform, error_app)
186
187
        self.assertEqual(len(events_request_appid(next_month)), 0)
188
        self.assertEqual(len(events_request_appid_platform(next_month)), 0)
189
190
        with freeze_time(next_month):
191
            add_app_statistics(userid, platform, success_app)
192
193
        self.assertEqual(len(events_request_appid(next_month)), 1)
194
        self.assertEqual(len(events_request_appid_platform(next_month)), 1)
195
        self.assertEqual(len(events_new_appid(next_month)), 0)
196
        self.assertEqual(len(events_request_appid_version(next_month)), 1)
197
        self.assertEqual(len(events_new_appid_platform(next_month)), 0)
198
        self.assertEqual(len(events_request_appid_channel()), 1)
199
        self.assertEqual(len(events_request_appid_platform_version()), 1)
200
201
        self.assertIn(userid, events_request_appid(next_month))
202
        self.assertIn(userid, events_request_appid_platform(next_month))
203
204
    def test_add_app_live_statistics(self):
205
        request = parse_request(fixtures.request_update_check)
206
        app = request.findall('app')[0]
207
208
        now = datetime.utcnow()
209
        userid = 1
210
        platform = 'win'
211
212
        appid = app.get('appid')
213
        version = app.get('version')
214
215
        events_appid_version = HourEvents('online:{}:{}'.format(appid, version), now.year, now.month, now.day, now.hour)
216
        events_appid_platform_version = HourEvents('online:{}:{}:{}'.format(appid, platform, version), now.year, now.month, now.day, now.hour)
217
218
        self.assertEqual(len(events_appid_version), 0)
219
        self.assertEqual(len(events_appid_platform_version), 0)
220
221
        add_app_live_statistics(userid, platform, app)
222
223
        self.assertEqual(len(events_appid_version), 1)
224
        self.assertEqual(len(events_appid_platform_version), 1)
225
226
        self.assertIn(userid, events_appid_version)
227
        self.assertIn(userid, events_appid_platform_version)
228
229
    def test_is_user_active(self):
230
        userid = '{F07B3878-CD6F-4B96-B52F-95C4D23077E0}'
231
        id = get_id(userid)
232
233
        self.assertTrue(is_user_active(ACTIVE_USERS_DICT_CHOICES['all'], userid))
234
        self.assertFalse(is_user_active(ACTIVE_USERS_DICT_CHOICES['week'], userid))
235
        self.assertFalse(is_user_active(ACTIVE_USERS_DICT_CHOICES['month'], userid))
236
237
        mark_event('request', id)
238
239
        self.assertTrue(is_user_active(ACTIVE_USERS_DICT_CHOICES['all'], userid))
240
        self.assertTrue(is_user_active(ACTIVE_USERS_DICT_CHOICES['week'], userid))
241
        self.assertTrue(is_user_active(ACTIVE_USERS_DICT_CHOICES['month'], userid))
242
243
    def test_get_kwargs_for_model(self):
244
        os = dict(platform="win",
245
                  version="6.1",
246
                  sp="",
247
                  arch="x64")
248
        kwargs = get_kwargs_for_model(Os, os)
249
        self.assertDictEqual(kwargs, dict(platform="win",
250
                                          version="6.1",
251
                                          sp="",
252
                                          arch="x64",
253
                                          id=None))
254
255
    def test_parse_os(self):
256
        request = parse_request(fixtures.request_event)
257
        os = parse_os(request.os)
258
        self.assertIsInstance(os, Os)
259
        self.assertEqual(os.platform, 'win')
260
        self.assertEqual(os.version, '6.1')
261
        self.assertEqual(os.sp, '')
262
        self.assertEqual(os.arch, 'x64')
263
264
    def test_parse_hw(self):
265
        hw = dict(sse2="1")
266
        hw = parse_hw(hw)
267
        self.assertIsInstance(hw, Hw)
268
        self.assertEqual(hw.sse, None)
269
        self.assertEqual(hw.sse2, 1)
270
        self.assertEqual(hw.sse3, None)
271
        self.assertEqual(hw.ssse3, None)
272
        self.assertEqual(hw.sse41, None)
273
        self.assertEqual(hw.sse42, None)
274
        self.assertEqual(hw.avx, None)
275
        self.assertEqual(hw.physmemory, None)
276
277
    def test_parse_request(self):
278
        request = parse_request(fixtures.request_event)
279
        req = parse_req(request)
280
        self.assertIsInstance(req, Request)
281
        self.assertEqual(req.version, Request._meta.get_field_by_name('version')[0].to_python('1.3.23.0'))
282
        self.assertEqual(req.ismachine, 1)
283
        self.assertEqual(req.sessionid, '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}')
284
        self.assertEqual(req.userid, '{D0BBD725-742D-44ae-8D46-0231E881D58E}')
285
        self.assertEqual(req.originurl, None)
286
        self.assertEqual(req.testsource, 'ossdev')
287
        self.assertEqual(req.updaterchannel, None)
288
289
    def test_parse_apps(self):
290
        request = parse_request(fixtures.request_event)
291
        req = parse_req(request)
292
        req.os = parse_os(request.os)
293
        req.hw = parse_hw(request.hw) if request.get('hw') else None
294
        req.save()
295
296
        apps = parse_apps(request.findall('app'), req)
297
        self.assertEqual(len(apps), 1)
298
        app = apps[0]
299
        self.assertIsInstance(app, AppRequest)
300
        self.assertEqual(app.version, None)
301
        self.assertEqual(app.nextversion, Request._meta.get_field_by_name('version')[0].to_python('13.0.782.112'))
302
        self.assertEqual(app.lang, 'en')
303
        self.assertEqual(app.tag, None)
304
        self.assertEqual(app.installage, 6)
305
        self.assertEqual(app.appid, '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}')
306
307
    def test_parse_events(self):
308
        request = parse_request(fixtures.request_event)
309
        events = request.findall('app')[0].findall('event')
310
        events = parse_events(events)
311
        self.assertEqual(len(events), 3)
312
        event = events[0]
313
        self.assertIsInstance(event, Event)
314
        self.assertEqual(event.eventtype, 9)
315
        self.assertEqual(event.eventresult, 1)
316
        self.assertEqual(event.errorcode, 0)
317
        self.assertEqual(event.extracode1, 0)
318
        self.assertEqual(event.download_time_ms, None)
319
        self.assertEqual(event.downloaded, None)
320
        self.assertEqual(event.total, None)
321
        self.assertEqual(event.update_check_time_ms, None)
322
        self.assertEqual(event.install_time_ms, None)
323
        self.assertEqual(event.source_url_index, None)
324
        self.assertEqual(event.state_cancelled, None)
325
        self.assertEqual(event.time_since_update_available_ms, None)
326
        self.assertEqual(event.time_since_download_start_ms, None)
327
        self.assertEqual(event.nextversion, None)
328
        self.assertEqual(event.previousversion, None)
329
330
    def test_collect_statistics(self):
331
        request = parse_request(fixtures.request_event)
332
333
        self.assertEqual(Os.objects.all().count(), 0)
334
        self.assertEqual(Hw.objects.all().count(), 0)
335
        self.assertEqual(Request.objects.all().count(), 0)
336
        self.assertEqual(AppRequest.objects.all().count(), 0)
337
        self.assertEqual(Event.objects.all().count(), 0)
338
339
        collect_statistics(request)
340
341
        self.assertEqual(Os.objects.all().count(), 1)
342
        self.assertEqual(Hw.objects.all().count(), 0)
343
        self.assertEqual(Request.objects.all().count(), 1)
344
        self.assertEqual(AppRequest.objects.all().count(), 1)
345
        self.assertEqual(Event.objects.all().count(), 3)
346
347
        os = Os.objects.get()
348
        req = Request.objects.get()
349
        app_req = AppRequest.objects.get()
350
        events = Event.objects.all()
351
352
        self.assertEqual(os.platform, 'win')
353
        self.assertEqual(os.version, '6.1')
354
        self.assertEqual(os.sp, '')
355
        self.assertEqual(os.arch, 'x64')
356
357
        self.assertEqual(req.version, Request._meta.get_field_by_name('version')[0].to_python('1.3.23.0'))
358
        self.assertEqual(req.ismachine, 1)
359
        self.assertEqual(req.sessionid, '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}')
360
        self.assertEqual(req.userid, '{D0BBD725-742D-44ae-8D46-0231E881D58E}')
361
        self.assertEqual(req.originurl, None)
362
        self.assertEqual(req.testsource, 'ossdev')
363
        self.assertEqual(req.updaterchannel, None)
364
        self.assertEqual(req.os, os)
365
        self.assertEqual(req.hw, None)
366
367
        self.assertEqual(app_req.version, None)
368
        self.assertEqual(app_req.nextversion, Request._meta.get_field_by_name('version')[0].to_python('13.0.782.112'))
369
        self.assertEqual(app_req.lang, 'en')
370
        self.assertEqual(app_req.tag, None)
371
        self.assertEqual(app_req.installage, 6)
372
        self.assertEqual(app_req.appid, '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}')
373
        self.assertEqual(app_req.request, req)
374
375
        event = events[0]
376
377
        self.assertEqual(event.eventtype, 9)
378
        self.assertEqual(event.eventresult, 1)
379
        self.assertEqual(event.errorcode, 0)
380
        self.assertEqual(event.extracode1, 0)
381
        self.assertEqual(event.download_time_ms, None)
382
        self.assertEqual(event.downloaded, None)
383
        self.assertEqual(event.total, None)
384
        self.assertEqual(event.update_check_time_ms, None)
385
        self.assertEqual(event.install_time_ms, None)
386
        self.assertEqual(event.source_url_index, None)
387
        self.assertEqual(event.state_cancelled, None)
388
        self.assertEqual(event.time_since_update_available_ms, None)
389
        self.assertEqual(event.time_since_download_start_ms, None)
390
        self.assertEqual(event.nextversion, None)
391
        self.assertEqual(event.previousversion, None)
392
393
        for e in events:
394
            self.assertIn(e, app_req.events.all())
395
396
    def test_update_live_statistics_install(self):
397
        request = parse_request(fixtures.request_event_install_success)
398 View Code Duplication
        apps = request.findall('app')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
399
        app = apps[0]
400
401
        now = datetime.utcnow()
402
        userid = 1
403
        platform = 'win'
404
405
        appid = app.get('appid')
406
        version_1 = '0.0.0.1'
407
        version_2 = '0.0.0.2'
408
409
        events_appid_version_1 = HourEvents('online:{}:{}'.format(appid, version_1), now.year, now.month, now.day, now.hour)
410
        events_appid_platform_version_1 = HourEvents('online:{}:{}:{}'.format(appid, platform, version_1), now.year, now.month, now.day, now.hour)
411
412
        self.assertEqual(len(events_appid_version_1), 0)
413
        self.assertEqual(len(events_appid_platform_version_1), 0)
414
415
        update_live_statistics(userid, apps, platform)
416
417
        self.assertEqual(len(events_appid_version_1), 1)
418
        self.assertEqual(len(events_appid_platform_version_1), 1)
419
420
        request = parse_request(fixtures.request_event_update_success)
421
        apps = request.findall('app')
422
423
        update_live_statistics(userid, apps, platform)
424
425
        events_appid_version_1 = HourEvents('online:{}:{}'.format(appid, version_1), now.year, now.month, now.day, now.hour)
426
        events_appid_platform_version_1 = HourEvents('online:{}:{}:{}'.format(appid, platform, version_1), now.year, now.month, now.day, now.hour)
427
        events_appid_version_2 = HourEvents('online:{}:{}'.format(appid, version_2), now.year, now.month, now.day, now.hour)
428
        events_appid_platform_version_2 = HourEvents('online:{}:{}:{}'.format(appid, platform, version_2), now.year, now.month, now.day, now.hour)
429
430
        self.assertEqual(len(events_appid_version_1), 0)
431
        self.assertEqual(len(events_appid_platform_version_1), 0)
432
        self.assertEqual(len(events_appid_version_2), 1)
433
        self.assertEqual(len(events_appid_platform_version_2), 1)
434
435
        request = parse_request(fixtures.request_event_uninstall_success)
436
        apps = request.findall('app')
437
438
        update_live_statistics(userid, apps, platform)
439
440
        events_appid_version_2 = HourEvents('online:{}:{}'.format(appid, version_2),
441
                                            now.year, now.month, now.day, now.hour)
442
        events_appid_platform_version_2 = HourEvents('online:{}:{}:{}'.format(appid, platform, version_2),
443
                                                     now.year, now.month, now.day, now.hour)
444
445
        self.assertEqual(len(events_appid_version_2), 1)
446
        self.assertEqual(len(events_appid_platform_version_2), 1)
447
448
    def test_update_live_statistics_updatecheck(self):
449
        request = parse_request(fixtures.request_update_check)
450
        apps = request.findall('app')
451
        app = apps[0]
452
453
        now = datetime.utcnow()
454
        userid = 1
455
        platform = 'win'
456
457
        appid = app.get('appid')
458
        version = app.get('version')
459
460
        events_appid_version = HourEvents('online:{}:{}'.format(appid, version), now.year, now.month, now.day, now.hour)
461
        events_appid_platform_version = HourEvents('online:{}:{}:{}'.format(appid, platform, version), now.year, now.month, now.day, now.hour)
462
463
        self.assertEqual(len(events_appid_version), 0)
464
        self.assertEqual(len(events_appid_platform_version), 0)
465
466
        update_live_statistics(userid, apps, platform)
467
468
        self.assertEqual(len(events_appid_version), 1)
469
        self.assertEqual(len(events_appid_platform_version), 1)
470
471
472
class GetStatisticsTest(TestCase):
473
    maxDiff = None
474
475
    def _generate_fake_statistics(self):
476
        now = datetime.now()
477
        year = now.year
478
        n_users = 12
479
480
        for i in range(1, n_users+1):
481
            date = datetime(year=year, month=i, day=10)
482
            for id in range(1, i + 1):
483
                user_id = UUID(int=id)
484
                userid_counting(user_id, self.install_app_list, self.platform.name, now=date)
485
                user_id = UUID(int=n_users + id)
486
                mac_userid_counting(user_id, self.mac_app, 'mac', now=date)
487
            userid_counting(UUID(int=i), self.uninstall_app_list, self.platform.name, now=date)
488
489
490
    @temporary_media_root()
491
    def setUp(self):
492
        redis.flushdb()
493
        self.app = Application.objects.create(id='app', name='app')
494
        self.channel = Channel.objects.create(name='stable')
495
        self.platform = Platform.objects.create(name='win')
496
        self.version1 = Version.objects.create(
497
            app=self.app,
498
            platform=self.platform,
499
            channel=self.channel,
500
            version='1.0.0.0',
501
            file=SimpleUploadedFile('./chrome_installer.exe', False))
502
        self.version2 = Version.objects.create(
503
            app=self.app,
504
            platform=self.platform,
505
            channel=self.channel,
506
            version='2.0.0.0',
507
            file=SimpleUploadedFile('./chrome_installer.exe', False))
508
        self.mac_version = SparkleVersion.objects.create(
509
            app=self.app,
510
            channel=self.channel,
511
            version='782.112',
512
            short_version='13.0.782.112',
513
            dsa_signature='MCwCFCdoW13VBGJWIfIklKxQVyetgxE7AhQTVuY9uQT0KOV1UEk21epBsGZMPg==',
514
            file=SimpleUploadedFile('./chrome.dmg', b'_' * 23963192),
515
            file_size=23963192)
516
517
        app_kwargs = dict(appid=self.app.id, version=str(self.version1.version))
518
        install_app = create_app_xml(events=[fixtures.event_install_success], **app_kwargs)
519
        uninstall_app = create_app_xml(events=[fixtures.event_uninstall_success], **app_kwargs)
520
        self.install_app_list = [install_app]
521
        self.uninstall_app_list = [uninstall_app]
522
        self.mac_app = dict(appid=self.app.id, version=str(self.mac_version.short_version))
523
524
        self._generate_fake_statistics()
525
        now = datetime.now()
526
        win_updates = [(datetime(now.year, x, 1).strftime("%Y-%m"), x - 1) for x in range(1, 13)]
527
        win_installs = [(datetime(now.year, x, 1).strftime("%Y-%m"), 1) for x in range(1, 13)]
528
        uninstalls = [(datetime(now.year, x, 1).strftime("%Y-%m"), 1) for x in range(1, 13)]
529
        mac_updates = [(datetime(now.year, x, 1).strftime("%Y-%m"), x - 1) for x in range(1, 13)]
530
        mac_installs = [(datetime(now.year, x, 1).strftime("%Y-%m"), 1) for x in range(1, 13)]
531
        total_installs = map(lambda x, y: (x[0], x[1] + y[1]), win_installs, mac_installs)
532
        total_updates = map(lambda x, y: (x[0], x[1] + y[1]), win_updates, mac_updates)
533
        self.users_statistics = dict(new=total_installs, updates=total_updates, uninstalls=uninstalls)
534
        self.win_users_statistics = dict(new=win_installs, updates=win_updates, uninstalls=uninstalls)
535
        self.mac_users_statistics = dict(new=mac_installs, updates=mac_updates)
536
537
538
    def tearDown(self):
539
        redis.flushdb()
540
541
    def test_get_users_statistics_months(self):
542
        self.assertDictEqual(get_users_statistics_months(app_id=self.app.id), self.users_statistics)
543
        self.assertDictEqual(get_users_statistics_months(app_id=self.app.id, platform='win'), self.win_users_statistics)
544
        self.assertDictEqual(get_users_statistics_months(app_id=self.app.id, platform='mac'), self.mac_users_statistics)
545
546
547
    def test_get_chanels_statistics(self):
548
        now = datetime.now()
549
        with freeze_time(datetime(year=now.year, month=now.month, day=10)):
550
            self.assertListEqual(get_channel_statistics(self.app.id), [('stable', now.month*2)])
551
552
    def test_get_users_versions(self):
553
        now = datetime.now()
554
        expected = dict(win={'1.0.0.0': now.month}, mac={'13.0.782.112': now.month})
555
        with freeze_time(datetime(year=now.year, month=now.month, day=10)):
556
            self.assertDictEqual(get_users_versions(self.app.id), expected)
557