Add validation of db before and after modification
Add various consistency checks of the database:
- no duplicate extension SDKs
- no duplicate module requirements in one SDK
- no version requirements "moving backwards"
..with associated tests.
Also add verification of the checked in database to presubmit tests
(the build of the binarypb should also fail).
Bug: 173188089
Test: atest gen_sdk_test
Change-Id: I10436cdde1e8829065d77be53d5f10b7264a5a58
diff --git a/gen_sdk/Android.bp b/gen_sdk/Android.bp
index b9ac715..c5890fb 100644
--- a/gen_sdk/Android.bp
+++ b/gen_sdk/Android.bp
@@ -28,7 +28,10 @@
sh_test_host {
name: "gen_sdk_test",
src: "gen_sdk_test.sh",
- data: ["testdata/**/*"],
+ data: [
+ "extensions_db.textpb",
+ "testdata/**/*"
+ ],
required: ["gen_sdk"],
test_suites: ["general-tests"],
}
diff --git a/gen_sdk/gen_sdk.py b/gen_sdk/gen_sdk.py
index c85243c..3353fd4 100644
--- a/gen_sdk/gen_sdk.py
+++ b/gen_sdk/gen_sdk.py
@@ -19,6 +19,9 @@
# Print a binary representation of the proto database.
$ gen_sdk --action print_binary
+# Validate the database
+$ gen_sdk --action validate
+
# Create a new SDK
$ gen_sdk --action new_sdk --sdk 1 --modules=IPSEC,SDK_EXTENSIONS
"""
@@ -45,10 +48,10 @@
)
parser.add_argument(
'--action',
- choices=['print_binary', 'new_sdk'],
+ choices=['print_binary', 'new_sdk', 'validate'],
metavar='ACTION',
required=True,
- help='Which action to take (print_binary|new_sdk).'
+ help='Which action to take (print_binary|new_sdk|validate).'
)
parser.add_argument(
'--sdk',
@@ -69,6 +72,41 @@
sys.stdout.buffer.write(database.SerializeToString())
+def ValidateDatabase(database, dbname):
+ def find_duplicate(l):
+ s = set()
+ for i in l:
+ if i in s:
+ return i
+ s.add(i)
+ return None
+
+ def find_bug():
+ dupe = find_duplicate([v.version for v in database.versions])
+ if dupe:
+ return 'Found duplicate extension version: %d' % dupe
+
+ for version in database.versions:
+ dupe = find_duplicate([r.module for r in version.requirements])
+ if dupe:
+ return 'Found duplicate module requirement for %s in single version %s' % (dupe, version)
+
+ prev_requirements = {}
+ for version in sorted(database.versions, key=lambda v: v.version):
+ for requirement in version.requirements:
+ if requirement.module in prev_requirements:
+ prev = prev_requirements[requirement.module]
+ if prev.version > requirement.version.version:
+ return 'Found module requirement moving backwards: %s in %s' % (requirement, version)
+ prev_requirements[requirement.module] = requirement.version
+ return None
+
+ err = find_bug()
+ if err is not None:
+ print('%s not valid, aborting:\n %s' % (dbname, err))
+ sys.exit(1)
+
+
def NewSdk(database, new_version, modules):
new_requirements = {}
@@ -98,12 +136,16 @@
if args.modules:
modules = [SdkModule.Value(m) for m in args.modules.split(',')]
+ ValidateDatabase(database, 'Input database')
+
{
+ 'validate': lambda : print('Validated database'),
'print_binary': lambda : PrintBinary(database),
'new_sdk': lambda : NewSdk(database, args.sdk, modules)
}[args.action]()
if args.action in ['new_sdk']:
+ ValidateDatabase(database, 'Post-modification database')
with args.database.open('w') as f:
f.write(google.protobuf.text_format.MessageToString(database))
diff --git a/gen_sdk/gen_sdk_test.sh b/gen_sdk/gen_sdk_test.sh
index 80e21ca..bdf35b7 100644
--- a/gen_sdk/gen_sdk_test.sh
+++ b/gen_sdk/gen_sdk_test.sh
@@ -42,3 +42,41 @@
diff -u0 testdata/test_extensions_db.textpb extensions_db.textpb
}
test_new_sdk
+
+# Verifies the tool won't allow bogus SDK updates
+function test_validate() {
+ set +e
+
+ rm -f extensions_db.textpb && echo bogus > extensions_db.textpb
+ if gen_sdk --action validate; then
+ echo "expected validate to fail on bogus db"
+ exit 1
+ fi
+
+ rm -f extensions_db.textpb && touch extensions_db.textpb
+ gen_sdk --action new_sdk --sdk 1 --modules MEDIA_PROVIDER
+ if gen_sdk --action new_sdk --sdk 1 --modules SDK_EXTENSIONS; then
+ echo "FAILED: expected duplicate sdk numbers to fail"
+ echo "DB:"
+ cat extensions_db.textpb
+ exit 1
+ fi
+
+ if gen_sdk --action validate --database testdata/dupe_req.textpb; then
+ echo "FAILED: expected duplicate module in one sdk level to fail"
+ exit 1
+ fi
+
+ if gen_sdk --action validate --database testdata/backward_req.textpb; then
+ echo "FAILED: expect version requirement going backward to fail"
+ exit 1
+ fi
+
+ set -e
+}
+test_validate
+
+function test_checked_in_db() {
+ gen_sdk --action validate --database extensions_db.textpb
+}
+test_checked_in_db
diff --git a/gen_sdk/testdata/backward_req.textpb b/gen_sdk/testdata/backward_req.textpb
new file mode 100644
index 0000000..f77604a
--- /dev/null
+++ b/gen_sdk/testdata/backward_req.textpb
@@ -0,0 +1,30 @@
+versions {
+ version: 1
+ requirements {
+ module: MEDIA_PROVIDER
+ version {
+ version: 2
+ }
+ }
+}
+versions {
+ version: 2
+ requirements {
+ module: MEDIA_PROVIDER
+ version {
+ version: 1
+ }
+ }
+ requirements {
+ module: MEDIA
+ version {
+ version: 2
+ }
+ }
+ requirements {
+ module: IPSEC
+ version {
+ version: 2
+ }
+ }
+}
diff --git a/gen_sdk/testdata/dupe_req.textpb b/gen_sdk/testdata/dupe_req.textpb
new file mode 100644
index 0000000..1280379
--- /dev/null
+++ b/gen_sdk/testdata/dupe_req.textpb
@@ -0,0 +1,15 @@
+versions {
+ version: 1
+ requirements {
+ module: MEDIA_PROVIDER
+ version {
+ version: 1
+ }
+ }
+ requirements {
+ module: MEDIA_PROVIDER
+ version {
+ version: 2
+ }
+ }
+}