#!/usr/bin/env python # coding: utf-8 # Gets one ping per client who has signable add-ons installed and active. Each of pings is a list of addons for a client # In[8]: import ujson as json from moztelemetry.spark import get_pings, get_one_ping_per_client def extract(ping): ping = json.loads(ping) addons = [] activeAddons = ping["environment"]["addons"]["activeAddons"] for id in activeAddons.keys(): addon = activeAddons[id] if "signedState" in addon: addons.append(addon) return { "clientID": ping["clientID"], "addons": addons } pings = get_pings(sc, app="Firefox", channel="nightly", build_id=("20150603000000", "20150610999999"), fraction=1) # Filter to pings that have signable add-ons pings = pings.map(extract) pings = pings.filter(lambda x: len(x["addons"]) > 0) # Reduce to one per client pings = get_one_ping_per_client(pings).map(lambda x: x["addons"]) pings.count() # Reduces to only the add-ons that were signed by AMO. Each of expected is a list of addons for a client # In[9]: def only_signed(addons): return list(filter(lambda x: x["version"][-9:] == ".1-signed", addons)) expected = pings.map(only_signed).filter(lambda x: len(x) > 0) expected.count() # In[10]: # Reduces a list of add-ons to only those that pass a check function def reduce_addon_state(check): def mapper(addons): return list(filter(check, addons)) return mapper # Gets the number of clients that have at least one add-on installed that doesn't meet the signing requirements (signedState <= 0) # In[11]: upset_users = pings.map(reduce_addon_state(lambda a: a["signedState"] <= 0)).filter(lambda x: len(x) > 0) upset_users.count() # Same again but only for add-ons that weren't sideloaded # In[12]: def not_foreign(addon): if not "foreignInstall" in addon: return True return addon["foreignInstall"] == "false" upset_no_foreign = pings.map(reduce_addon_state(lambda a: not_foreign(a) and a["signedState"] <= 0)).filter(lambda x: len(x) > 0) upset_no_foreign.count() # Gets the number of clients that have at least one AMO signed add-on installed that shows as broken (signedState < 0) # In[13]: broken = expected.map(reduce_addon_state(lambda a: a["signedState"] < 0)).filter(lambda x: len(x) > 0) broken.count() # Gets the number of clients that have at least one AMO signed add-on installed that shows as not signed (signedState == 0) # In[14]: missing = expected.map(reduce_addon_state(lambda a: a["signedState"] == 0)).filter(lambda x: len(x) > 0) missing.count()