Skip to content

Commit

Permalink
Return more information about Rules with Releases (#990)
Browse files Browse the repository at this point in the history
* First crack at returning additional rule info with releases.

* Reformat.

* Remove some unneeded queries.

* Revert accidental change and restrict npm package due to bustage.

* Address review comments.
  • Loading branch information
bhearsum committed Aug 28, 2019
1 parent 8c6d243 commit 7a1f80e
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 28 deletions.
28 changes: 13 additions & 15 deletions auslib/db.py
Expand Up @@ -1783,21 +1783,15 @@ def getPotentialRequiredSignoffs(self, affected_rows, transaction=None):
# to them. We need to find these Rules, and then return _their_
# Required Signoffs.
if info:
# get all rules as one query
q_rules = [self.db.rules.rule_id.in_(tuple([rule_id for row in info for rule_id in row["rule_ids"]]))]
all_rules = self.db.rules.select(where=q_rules, transaction=transaction)

# map rules according to rule_id
rules_map = {rule["rule_id"]: rule for rule in all_rules}
relevant_rules = [rule_info for row in info for rule_info in row["rule_info"].values()]

# get all rs as one query
all_rs = self.db.rules.getPotentialRequiredSignoffs(all_rules, transaction=transaction)
all_rs = self.db.rules.getPotentialRequiredSignoffs(relevant_rules, transaction=transaction)

for row in info:
rs = []
potential_required_signoffs[row["name"]] = []
for rule_id in row["rule_ids"]:
rule = rules_map[rule_id]
for rule in row["rule_info"].values():
_rs = all_rs[(rule["product"], rule["channel"])]
rs.extend(_rs)
potential_required_signoffs[row["name"]] = rs
Expand Down Expand Up @@ -1847,17 +1841,21 @@ def getReleaseInfo(self, names=None, product=None, limit=None, transaction=None,
((self.db.releases.name == self.db.rules.mapping) | (self.db.releases.name == self.db.rules.fallbackMapping)),
)
if transaction:
ref_list = transaction.execute(select([self.db.releases.name, self.db.rules.rule_id]).select_from(j)).fetchall()
ref_list = transaction.execute(
select([self.db.releases.name, self.db.rules.rule_id, self.db.rules.product, self.db.rules.channel]).select_from(j)
).fetchall()
else:
ref_list = self.getEngine().execute(select([self.db.releases.name, self.db.rules.rule_id]).select_from(j)).fetchall()
ref_list = (
self.getEngine()
.execute(select([self.db.releases.name, self.db.rules.rule_id, self.db.rules.product, self.db.rules.channel]).select_from(j))
.fetchall()
)

for row in rows:
refs = [ref for ref in ref_list if ref[0] == row["name"]]
ref_list = [ref for ref in ref_list if ref[0] != row["name"]]
if len(refs) > 0:
row["rule_ids"] = [ref[1] for ref in refs]
else:
row["rule_ids"] = []
row["rule_ids"] = [ref[1] for ref in refs]
row["rule_info"] = {str(ref[1]): {"product": ref[2], "channel": ref[3]} for ref in refs}

return rows

Expand Down
20 changes: 18 additions & 2 deletions auslib/test/admin/views/test_releases.py
Expand Up @@ -1207,8 +1207,19 @@ def testGetReleasesNamePrefix(self):
"""
{
"releases": [
{"data_version": 1, "name": "a", "product": "a", "read_only": false, "rule_ids": [3, 4, 6, 7, 8, 9], "required_signoffs": {"releng": 1}},
{"data_version": 1, "name": "ab", "product": "a", "read_only": false, "rule_ids": [], "required_signoffs": {}}
{"data_version": 1, "name": "a", "product": "a", "read_only": false,
"rule_ids": [3, 4, 6, 7, 8, 9],
"rule_info": {
"3": {"product": "a", "channel": "a"},
"4": {"product": "fake", "channel": "a"},
"6": {"product": "fake", "channel": "e"},
"7": {"product": "fake", "channel": "c"},
"8": {"product": "fake2", "channel": "c"},
"9": {"product": "fake3", "channel": "c"}
},
"required_signoffs": {"releng": 1}
},
{"data_version": 1, "name": "ab", "product": "a", "read_only": false, "rule_ids": [], "rule_info": {}, "required_signoffs": {}}
]
}
"""
Expand Down Expand Up @@ -2122,6 +2133,7 @@ def testPresentRuleIdField(self):
releases = self._get("/releases")
releases_data = json.loads(releases.data)
self.assertTrue("rule_ids" in releases_data["releases"][0])
self.assertTrue("rule_info" in releases_data["releases"][0])

def testMappingIncluded(self):
rel_name = "ab"
Expand All @@ -2131,7 +2143,9 @@ def testMappingIncluded(self):
releases_data = json.loads(releases.data)
not_mapped_rel = next(rel for rel in releases_data["releases"] if rel["name"] == rel_name)
self.assertEqual(len(not_mapped_rel["rule_ids"]), 0)
self.assertEqual(len(not_mapped_rel["rule_info"]), 0)
self.assertFalse(rule_id in not_mapped_rel["rule_ids"])
self.assertFalse(rule_id in not_mapped_rel["rule_info"].keys())

dbo.rules.t.insert().execute(
id=rule_id, priority=100, version="3.5", buildTarget="d", backgroundRate=100, mapping=rel_name, update_type="minor", data_version=1
Expand All @@ -2141,4 +2155,6 @@ def testMappingIncluded(self):
releases_data = json.loads(releases.data)
mapped_rel = next(rel for rel in releases_data["releases"] if rel["name"] == rel_name)
self.assertEqual(len(mapped_rel["rule_ids"]), 1)
self.assertEqual(len(mapped_rel["rule_info"]), 1)
self.assertTrue(rule_id in mapped_rel["rule_ids"])
self.assertTrue(str(rule_id) in mapped_rel["rule_info"].keys())
28 changes: 18 additions & 10 deletions auslib/test/test_db.py
Expand Up @@ -3591,27 +3591,34 @@ def testGetReleaseBlobNonExistentRelease(self):
def testGetReleaseInfoAll(self):
releases = self.releases.getReleaseInfo()
expected = [
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="b", product="b", data_version=1, read_only=False, rule_ids=[]),
dict(name="c", product="c", data_version=1, read_only=False, rule_ids=[2]),
dict(name="h", product="b", data_version=1, read_only=False, rule_ids=[1, 2]),
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
dict(name="b", product="b", data_version=1, read_only=False, rule_ids=[], rule_info={}),
dict(name="c", product="c", data_version=1, read_only=False, rule_ids=[2], rule_info={"2": {"product": "b", "channel": "h"}}),
dict(
name="h",
product="b",
data_version=1,
read_only=False,
rule_ids=[1, 2],
rule_info={"1": {"product": "b", "channel": "h"}, "2": {"product": "b", "channel": "h"}},
),
]
self.assertEqual(releases, expected)

def testGetReleaseInfoProduct(self):
releases = self.releases.getReleaseInfo(product="a")
expected = [
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
]
self.assertEqual(releases, expected)

def testGetReleaseInfoWithFallbackMapping(self):
self.releases.t.insert().execute(name="fallback", product="e", data=createBlob(dict(name="e", schema_version=1, hashFunction="sha512")), data_version=1)
self.rules.t.insert().execute(rule_id=4, priority=100, fallbackMapping="fallback", version="3.5", update_type="z", data_version=1)
releases = self.releases.getReleaseInfo(product="e")
expected = [dict(name="fallback", product="e", data_version=1, read_only=False, rule_ids=[4])]
expected = [dict(name="fallback", product="e", data_version=1, read_only=False, rule_ids=[4], rule_info={"4": {"product": None, "channel": None}})]
self.assertEqual(releases, expected)

def testGetReleaseInfoNoMatch(self):
Expand All @@ -3622,8 +3629,8 @@ def testGetReleaseInfoNoMatch(self):
def testGetReleaseInfoNamePrefix(self):
releases = self.releases.getReleaseInfo(name_prefix="a")
expected = [
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[]),
dict(name="a", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
dict(name="ab", product="a", data_version=1, read_only=False, rule_ids=[], rule_info={}),
]
self.assertEqual(releases, expected)

Expand All @@ -3635,6 +3642,7 @@ def testGetReleaseInfoNamePrefixNameOnly(self):
def testPresentRuleIdField(self):
releases = self.releases.getReleaseInfo()
self.assertTrue("rule_ids" in releases[0])
self.assertTrue("rule_info" in releases[0])

def testGetReleaseNames(self):
releases = self.releases.getReleaseNames()
Expand Down
9 changes: 9 additions & 0 deletions auslib/web/common/swagger/definitions.yml
Expand Up @@ -153,12 +153,21 @@ definitions:
type: integer
minimum: 0
example: [487, 589]
rule_info:
description: basic information about the rules that point to the requested release
type: object
properties:
product:
type: string
channel:
type: string
required:
- name
- product
- data_version
- read_only
- rule_ids
- rule_info

UpdateType:
title: Rule's update_type field
Expand Down
3 changes: 2 additions & 1 deletion ui/package.json
Expand Up @@ -21,7 +21,8 @@
"lineman-less": "0.1.0",
"phantomjs-prebuilt": "2.1.15",
"protractor": "1.8.0",
"testem": "1.18.4"
"testem": "1.18.4",
"follow-redirects": "1.7.0"
},
"scripts": {
"start": "./node_modules/.bin/lineman run",
Expand Down

0 comments on commit 7a1f80e

Please sign in to comment.