1114912d4b9dec67b02223ffa57ffab686442e332msarett#
2114912d4b9dec67b02223ffa57ffab686442e332msarett# Copyright 2015 Google Inc.
3114912d4b9dec67b02223ffa57ffab686442e332msarett#
4114912d4b9dec67b02223ffa57ffab686442e332msarett# Use of this source code is governed by a BSD-style license that can be
5114912d4b9dec67b02223ffa57ffab686442e332msarett# found in the LICENSE file.
6114912d4b9dec67b02223ffa57ffab686442e332msarett#
7114912d4b9dec67b02223ffa57ffab686442e332msarett
811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein#!/usr/bin/env python
911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
1011a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinusage = '''
1111a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinWrite extra flags to outfile for DM based on the bot name:
121e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet  $ python dm_flags.py outfile Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Debug
1311a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinOr run self-tests:
1411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  $ python dm_flags.py test
1511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein'''
1611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
1711a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinimport inspect
1811a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinimport json
1911a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinimport os
2011a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinimport sys
2111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
2211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
2311a2c503bd773572352a39fa4aef5d506ecfefbbmtkleindef lineno():
2411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  caller = inspect.stack()[1]  # Up one level to our caller.
2511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  return inspect.getframeinfo(caller[0]).lineno
2611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
2711a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
2811a2c503bd773572352a39fa4aef5d506ecfefbbmtkleincov_start = lineno()+1   # We care about coverage starting just past this def.
29f73e589c0d3d54371466dcaa0642925824df24d7mtkleindef get_args(bot):
3011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  args = []
3111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
32d9b6be197fe9cc75e068aaaf941455c13b2e38c3borenet  configs = ['565', '8888', 'gpu']
33e3aeaec7ddda15faa923d34b67b4cdba71f5d119borenet
34d9b6be197fe9cc75e068aaaf941455c13b2e38c3borenet  if 'Android' not in bot:
35d9b6be197fe9cc75e068aaaf941455c13b2e38c3borenet    configs.extend(('upright-matrix-8888', 'upright-matrix-gpu'))
36d9b6be197fe9cc75e068aaaf941455c13b2e38c3borenet    args.extend('--matrix 0 1 1 0'.split(' '))
37fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein
3832618cb857e245f1b0de932663d3215cebc2bc44mtklein  if '-GCE-' in bot:
3932618cb857e245f1b0de932663d3215cebc2bc44mtklein    configs.append('sp-8888')
4032618cb857e245f1b0de932663d3215cebc2bc44mtklein
41fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein  if 'TegraK1' in bot or 'GTX550Ti' in bot or 'GTX660' in bot or 'GT610' in bot:
42fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein    if 'Android' in bot:
43fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein      configs.append('nvprmsaa4')
44fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein    else:
45fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein      configs.append('nvprmsaa16')
46fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein
475abf584bcc21a488e04548e5a102265b17c11f83bsalomon  # The S4 crashes and the NP produces a long error stream when we run with
48d557462f1fd274400107dd28ea36900da51e42a6mtklein  # MSAA.  The Tegra2 and Tegra3 just don't support it.
495abf584bcc21a488e04548e5a102265b17c11f83bsalomon  if ('GalaxyS4'    not in bot and
50d557462f1fd274400107dd28ea36900da51e42a6mtklein      'NexusPlayer' not in bot and
51deee2980f41cb9586bb7a596cf99d25775f7c698stephana      'Tegra3'      not in bot and
52deee2980f41cb9586bb7a596cf99d25775f7c698stephana      'iOS'         not in bot):
535abf584bcc21a488e04548e5a102265b17c11f83bsalomon    if 'Android' in bot:
54fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein      configs.append('msaa4')
555abf584bcc21a488e04548e5a102265b17c11f83bsalomon    else:
56fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein      configs.append('msaa16')
5782b33dbcb2b29471c2c2740b00c0b9a0197c957emtklein  # Runs out of memory on Android bots and Daisy.  Everyone else seems fine.
58150d3503ede63564be83b9b083d2d3dd08462475mtklein  if 'Android' not in bot and 'Daisy' not in bot:
5984aada88ca9ed6c02787b7ca874b62061f6da9admtklein    configs.append('pdf')
605abf584bcc21a488e04548e5a102265b17c11f83bsalomon
6197025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet  # NP is running out of RAM when we run all these modes.  skia:3255
6297025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet  if 'NexusPlayer' not in bot:
6311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    configs.extend(mode + '-8888' for mode in
6411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein                   ['serialize', 'tiles_rt', 'pipe'])
6511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    configs.append('tiles_rt-gpu')
66ee2a3eaf996826ec603748c7f79d4d6b5cf0ecc3mtklein  if 'ANGLE' in bot:
67ee2a3eaf996826ec603748c7f79d4d6b5cf0ecc3mtklein    configs.append('angle')
6811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  args.append('--config')
6911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  args.extend(configs)
7011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
7197025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet  if 'GalaxyS' in bot:
7297025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet    args.extend(('--threads', '0'))
7397025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet
7411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  blacklist = []
7511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  # This image is too large to be a texture for many GPUs.
7654416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('gpu _ _ PANO_20121023_214540.jpg'.split(' '))
7754416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('msaa _ _ PANO_20121023_214540.jpg'.split(' '))
7811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
79114912d4b9dec67b02223ffa57ffab686442e332msarett  # Several of the newest version bmps fail on SkImageDecoder
8054416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode pal8os2v2.bmp'.split(' '))
8154416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode pal8v4.bmp'.split(' '))
8254416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode pal8v5.bmp'.split(' '))
8354416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgb16-565.bmp'.split(' '))
8454416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgb16-565pal.bmp'.split(' '))
8554416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgb32-111110.bmp'.split(' '))
8654416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgb32bf.bmp'.split(' '))
8754416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgba32.bmp'.split(' '))
8854416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgba32abf.bmp'.split(' '))
8954416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode rgb24largepal.bmp'.split(' '))
9054416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode pal8os2v2-16.bmp'.split(' '))
9154416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode pal8oversizepal.bmp'.split(' '))
922f273a1ed098fbd7a8af86b349dbd247de609a2amsarett  blacklist.extend('_ image decode pal4rletrns.bmp'.split(' '))
932f273a1ed098fbd7a8af86b349dbd247de609a2amsarett  blacklist.extend('_ image decode pal8rletrns.bmp'.split(' '))
943c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image decode 4bpp-pixeldata-cropped.bmp'.split(' '))
953c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image decode 8bpp-pixeldata-cropped.bmp'.split(' '))
963c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image decode 24bpp-pixeldata-cropped.bmp'.split(' '))
973c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image decode 32bpp-pixeldata-cropped.bmp'.split(' '))
9854416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image subset rgb24largepal.bmp'.split(' '))
9954416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image subset pal8os2v2-16.bmp'.split(' '))
10054416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image subset pal8oversizepal.bmp'.split(' '))
1013c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image subset 4bpp-pixeldata-cropped.bmp'.split(' '))
1023c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image subset 8bpp-pixeldata-cropped.bmp'.split(' '))
1033c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image subset 24bpp-pixeldata-cropped.bmp'.split(' '))
1043c309db75bb8c4c2b58724a0e2f6f3b387ca842cmsarett  blacklist.extend('_ image subset 32bpp-pixeldata-cropped.bmp'.split(' '))
105114912d4b9dec67b02223ffa57ffab686442e332msarett
106114912d4b9dec67b02223ffa57ffab686442e332msarett  # New ico files that fail on SkImageDecoder
10754416de52381ac11dd755100a8025debf595873adjsollen  blacklist.extend('_ image decode Hopstarter-Mac-Folders-Apple.ico'.split(' '))
108114912d4b9dec67b02223ffa57ffab686442e332msarett
109e2aab90979d8fa741b735d0df6870cd338d51dacmtklein  # Leon doesn't care about this, so why run it?
110e2aab90979d8fa741b735d0df6870cd338d51dacmtklein  if 'Win' in bot:
11154416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('_ image decode _'.split(' '))
11254416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('_ image subset _'.split(' '))
113e2aab90979d8fa741b735d0df6870cd338d51dacmtklein
11489c2a540a39d5b8bf50ee5395fe4848168270f4cegdaniel  # Certain gm's on win7 gpu and pdf are never finishing and keeping the test
11589c2a540a39d5b8bf50ee5395fe4848168270f4cegdaniel  # running forever
11689c2a540a39d5b8bf50ee5395fe4848168270f4cegdaniel  if 'Win7' in bot:
11754416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('msaa16 gm _ colorwheelnative'.split(' '))
11854416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('pdf gm _ fontmgr_iter_factory'.split(' '))
11989c2a540a39d5b8bf50ee5395fe4848168270f4cegdaniel
12011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  # Drawing SKPs or images into GPU canvases is a New Thing.
12111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  # It seems like we're running out of RAM on some Android bots, so start off
12211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  # with a very wide blacklist disabling all these tests on all Android bots.
12311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if 'Android' in bot:  # skia:3255
12454416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('gpu skp _ _ msaa skp _ _'.split(' '))
12554416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('gpu image decode _ msaa image decode _'.split(' '))
12654416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('gpu image subset _ msaa image subset _'.split(' '))
12711a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
128150d3503ede63564be83b9b083d2d3dd08462475mtklein  if 'Valgrind' in bot:
129de7665a6d5b0f11d87abcbbf495d504f5aa419cemtklein    # PDF + .webp -> jumps depending on uninitialized memory.  skia:3505
13054416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('pdf _ _ .webp'.split(' '))
131ce866873102e70421d9e532f19cf56905482054emtklein    # These take 18+ hours to run.
13254416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('pdf gm _ fontmgr_iter'.split(' '))
13354416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('pdf _ _ PANO_20121023_214540.jpg'.split(' '))
134fbcf0bd7ff87a55d978016a686dd7dd8fc32e993Mike Klein    blacklist.extend('pdf skp _ worldjournal'.split(' '))
13554416de52381ac11dd755100a8025debf595873adjsollen    blacklist.extend('pdf skp _ desk_baidu.skp'.split(' '))
13622ecae88eec772be86da34015090a2eb649b9511borenet    blacklist.extend('pdf skp _ desk_wikipedia.skp'.split(' '))
137150d3503ede63564be83b9b083d2d3dd08462475mtklein
138deee2980f41cb9586bb7a596cf99d25775f7c698stephana  if 'iOS' in bot:
139deee2980f41cb9586bb7a596cf99d25775f7c698stephana    blacklist.extend('gpu skp _ _ msaa skp _ _'.split(' '))
140deee2980f41cb9586bb7a596cf99d25775f7c698stephana    blacklist.extend('gpu image decode _ msaa image decode _'.split(' '))
141deee2980f41cb9586bb7a596cf99d25775f7c698stephana    blacklist.extend('gpu image subset _ msaa image subset _'.split(' '))
142deee2980f41cb9586bb7a596cf99d25775f7c698stephana    blacklist.extend('msaa16 gm _ tilemodesProcess'.split(' '))
143deee2980f41cb9586bb7a596cf99d25775f7c698stephana
144f4e0857fe9e7b606c36302a252f23a790427f899borenet  if 'GalaxyS4' in bot:
145f4e0857fe9e7b606c36302a252f23a790427f899borenet    # This occasionally runs forever. skia:3802
146f4e0857fe9e7b606c36302a252f23a790427f899borenet    blacklist.extend('tiles_rt-gpu gm _ imagefilterscropped'.split(' '))
147f4e0857fe9e7b606c36302a252f23a790427f899borenet
14811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if blacklist:
14911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    args.append('--blacklist')
15011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    args.extend(blacklist)
15111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
15211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  match = []
15311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if 'Valgrind' in bot: # skia:3021
15411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    match.append('~Threaded')
155905d01b95a6b3f7dd18701e211006bd80215d536mtklein  if 'TSAN' in bot: # skia:3562
156905d01b95a6b3f7dd18701e211006bd80215d536mtklein    match.append('~Math')
157905d01b95a6b3f7dd18701e211006bd80215d536mtklein
15897025e34d3e5916ec5ae5363a9ac44b776d2c1ddborenet  if 'GalaxyS3' in bot:  # skia:1699
15911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    match.append('~WritePixels')
16011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
16111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  # skia:3249: these images flakily don't decode on Android.
16211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if 'Android' in bot:
16311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    match.append('~tabl_mozilla_0')
16411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    match.append('~desk_yahoonews_0')
16511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
1664e2d3be035f8b2f88f3002da7ec53d013004952amtklein  if 'NexusPlayer' in bot:
1674e2d3be035f8b2f88f3002da7ec53d013004952amtklein    match.append('~ResourceCache')
1684e2d3be035f8b2f88f3002da7ec53d013004952amtklein
169deee2980f41cb9586bb7a596cf99d25775f7c698stephana  if 'iOS' in bot:
170deee2980f41cb9586bb7a596cf99d25775f7c698stephana    match.append('~WritePixels')
171deee2980f41cb9586bb7a596cf99d25775f7c698stephana
17211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if match:
17311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    args.append('--match')
17411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    args.extend(match)
17511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
17611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  return args
17711a2c503bd773572352a39fa4aef5d506ecfefbbmtkleincov_end = lineno()   # Don't care about code coverage past here.
17811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
17911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
18011a2c503bd773572352a39fa4aef5d506ecfefbbmtkleindef self_test():
18111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  import coverage  # This way the bots don't need coverage.py to be installed.
18211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  args = {}
18311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  cases = [
184e4b19c4593da5179b346b66b291e8f4f45af617fmtklein    'Pretend-iOS-Bot',
185fca5c88873cbf30f756bcb57e28df62f56c26d85mtklein    'Test-Android-GCC-Nexus9-GPU-TegraK1-Arm64-Debug',
1861e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Android-GCC-GalaxyS3-GPU-Mali400-Arm7-Debug',
187e4b19c4593da5179b346b66b291e8f4f45af617fmtklein    'Test-Android-GCC-GalaxyS4-GPU-SGX544-Arm7-Release',
1881e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Android-GCC-Nexus7-GPU-Tegra3-Arm7-Release',
1891e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Android-GCC-NexusPlayer-CPU-SSSE3-x86-Release',
1901e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Ubuntu-GCC-ShuttleA-GPU-GTX550Ti-x86_64-Release-Valgrind',
1911e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-TSAN',
1921e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Valgrind',
1931e37d1762c12b7498fdb9a77cefcec2777bb6b85borenet    'Test-Win7-MSVC-ShuttleA-GPU-HD2000-x86-Debug-ANGLE',
19411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  ]
19511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
19611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  cov = coverage.coverage()
19711a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  cov.start()
19811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  for case in cases:
199f73e589c0d3d54371466dcaa0642925824df24d7mtklein    args[case] = get_args(case)
20011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  cov.stop()
20111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
20211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  this_file = os.path.basename(__file__)
20311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  _, _, not_run, _ = cov.analysis(this_file)
20411a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  filtered = [line for line in not_run if line > cov_start and line < cov_end]
20511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if filtered:
20611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    print 'Lines not covered by test cases: ', filtered
20711a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    sys.exit(1)
20811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
20911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  golden = this_file.replace('.py', '.json')
21011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  with open(os.path.join(os.path.dirname(__file__), golden), 'w') as f:
21111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    json.dump(args, f, indent=2, sort_keys=True)
21211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
21311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
21411a2c503bd773572352a39fa4aef5d506ecfefbbmtkleinif __name__ == '__main__':
21511a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if len(sys.argv) == 2 and sys.argv[1] == 'test':
21611a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    self_test()
21711a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    sys.exit(0)
21811a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
21911a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  if len(sys.argv) != 3:
22011a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    print usage
22111a2c503bd773572352a39fa4aef5d506ecfefbbmtklein    sys.exit(1)
22211a2c503bd773572352a39fa4aef5d506ecfefbbmtklein
22311a2c503bd773572352a39fa4aef5d506ecfefbbmtklein  with open(sys.argv[1], 'w') as out:
224f73e589c0d3d54371466dcaa0642925824df24d7mtklein    json.dump(get_args(sys.argv[2]), out)
225