xref: /openbmc/linux/tools/hv/vmbus_testing (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1c48d8b04SBranden Bonaby#!/usr/bin/env python3
2c48d8b04SBranden Bonaby# SPDX-License-Identifier: GPL-2.0
3c48d8b04SBranden Bonaby#
4c48d8b04SBranden Bonaby# Program to allow users to fuzz test Hyper-V drivers
5c48d8b04SBranden Bonaby# by interfacing with Hyper-V debugfs attributes.
6c48d8b04SBranden Bonaby# Current test methods available:
7c48d8b04SBranden Bonaby#       1. delay testing
8c48d8b04SBranden Bonaby#
9c48d8b04SBranden Bonaby# Current file/directory structure of hyper-V debugfs:
10c48d8b04SBranden Bonaby#       /sys/kernel/debug/hyperv/UUID
11c48d8b04SBranden Bonaby#       /sys/kernel/debug/hyperv/UUID/<test-state filename>
12c48d8b04SBranden Bonaby#       /sys/kernel/debug/hyperv/UUID/<test-method sub-directory>
13c48d8b04SBranden Bonaby#
14c48d8b04SBranden Bonaby# author: Branden Bonaby <brandonbonaby94@gmail.com>
15c48d8b04SBranden Bonaby
16c48d8b04SBranden Bonabyimport os
17c48d8b04SBranden Bonabyimport cmd
18c48d8b04SBranden Bonabyimport argparse
19c48d8b04SBranden Bonabyimport glob
20c48d8b04SBranden Bonabyfrom argparse import RawDescriptionHelpFormatter
21c48d8b04SBranden Bonabyfrom argparse import RawTextHelpFormatter
22c48d8b04SBranden Bonabyfrom enum import Enum
23c48d8b04SBranden Bonaby
24c48d8b04SBranden Bonaby# Do not change unless, you change the debugfs attributes
25c48d8b04SBranden Bonaby# in /drivers/hv/debugfs.c. All fuzz testing
26c48d8b04SBranden Bonaby# attributes will start with "fuzz_test".
27c48d8b04SBranden Bonaby
28c48d8b04SBranden Bonaby# debugfs path for hyperv must exist before proceeding
29c48d8b04SBranden Bonabydebugfs_hyperv_path = "/sys/kernel/debug/hyperv"
30c48d8b04SBranden Bonabyif not os.path.isdir(debugfs_hyperv_path):
31c48d8b04SBranden Bonaby        print("{} doesn't exist/check permissions".format(debugfs_hyperv_path))
32c48d8b04SBranden Bonaby        exit(-1)
33c48d8b04SBranden Bonaby
34c48d8b04SBranden Bonabyclass dev_state(Enum):
35c48d8b04SBranden Bonaby        off = 0
36c48d8b04SBranden Bonaby        on = 1
37c48d8b04SBranden Bonaby
38c48d8b04SBranden Bonaby# File names, that correspond to the files created in
39c48d8b04SBranden Bonaby# /drivers/hv/debugfs.c
40c48d8b04SBranden Bonabyclass f_names(Enum):
41c48d8b04SBranden Bonaby        state_f = "fuzz_test_state"
42c48d8b04SBranden Bonaby        buff_f =  "fuzz_test_buffer_interrupt_delay"
43c48d8b04SBranden Bonaby        mess_f =  "fuzz_test_message_delay"
44c48d8b04SBranden Bonaby
45c48d8b04SBranden Bonaby# Both single_actions and all_actions are used
46c48d8b04SBranden Bonaby# for error checking and to allow for some subparser
47c48d8b04SBranden Bonaby# names to be abbreviated. Do not abbreviate the
48c48d8b04SBranden Bonaby# test method names, as it will become less intuitive
49c48d8b04SBranden Bonaby# as to what the user can do. If you do decide to
50c48d8b04SBranden Bonaby# abbreviate the test method name, make sure the main
51c48d8b04SBranden Bonaby# function reflects this change.
52c48d8b04SBranden Bonaby
53c48d8b04SBranden Bonabyall_actions = [
54c48d8b04SBranden Bonaby        "disable_all",
55c48d8b04SBranden Bonaby        "D",
56c48d8b04SBranden Bonaby        "enable_all",
57c48d8b04SBranden Bonaby        "view_all",
58c48d8b04SBranden Bonaby        "V"
59c48d8b04SBranden Bonaby]
60c48d8b04SBranden Bonaby
61c48d8b04SBranden Bonabysingle_actions = [
62c48d8b04SBranden Bonaby        "disable_single",
63c48d8b04SBranden Bonaby        "d",
64c48d8b04SBranden Bonaby        "enable_single",
65c48d8b04SBranden Bonaby        "view_single",
66c48d8b04SBranden Bonaby        "v"
67c48d8b04SBranden Bonaby]
68c48d8b04SBranden Bonaby
69c48d8b04SBranden Bonabydef main():
70c48d8b04SBranden Bonaby
71c48d8b04SBranden Bonaby        file_map = recursive_file_lookup(debugfs_hyperv_path, dict())
72c48d8b04SBranden Bonaby        args = parse_args()
73c48d8b04SBranden Bonaby        if (not args.action):
74c48d8b04SBranden Bonaby                print ("Error, no options selected...exiting")
75c48d8b04SBranden Bonaby                exit(-1)
76c48d8b04SBranden Bonaby        arg_set = { k for (k,v) in vars(args).items() if v and k != "action" }
77c48d8b04SBranden Bonaby        arg_set.add(args.action)
78c48d8b04SBranden Bonaby        path = args.path if "path" in arg_set else None
79c48d8b04SBranden Bonaby        if (path and path[-1] == "/"):
80c48d8b04SBranden Bonaby                path = path[:-1]
81c48d8b04SBranden Bonaby        validate_args_path(path, arg_set, file_map)
82c48d8b04SBranden Bonaby        if (path and "enable_single" in arg_set):
83c48d8b04SBranden Bonaby            state_path = locate_state(path, file_map)
84c48d8b04SBranden Bonaby            set_test_state(state_path, dev_state.on.value, args.quiet)
85c48d8b04SBranden Bonaby
86c48d8b04SBranden Bonaby        # Use subparsers as the key for different actions
87c48d8b04SBranden Bonaby        if ("delay" in arg_set):
88c48d8b04SBranden Bonaby                validate_delay_values(args.delay_time)
89c48d8b04SBranden Bonaby                if (args.enable_all):
90c48d8b04SBranden Bonaby                        set_delay_all_devices(file_map, args.delay_time,
91c48d8b04SBranden Bonaby                                              args.quiet)
92c48d8b04SBranden Bonaby                else:
93c48d8b04SBranden Bonaby                        set_delay_values(path, file_map, args.delay_time,
94c48d8b04SBranden Bonaby                                         args.quiet)
95c48d8b04SBranden Bonaby        elif ("disable_all" in arg_set or "D" in arg_set):
96c48d8b04SBranden Bonaby                disable_all_testing(file_map)
97c48d8b04SBranden Bonaby        elif ("disable_single" in arg_set or "d" in arg_set):
98c48d8b04SBranden Bonaby                disable_testing_single_device(path, file_map)
99c48d8b04SBranden Bonaby        elif ("view_all" in arg_set or "V" in arg_set):
100c48d8b04SBranden Bonaby                get_all_devices_test_status(file_map)
101c48d8b04SBranden Bonaby        elif ("view_single" in arg_set or  "v" in arg_set):
102c48d8b04SBranden Bonaby                get_device_test_values(path, file_map)
103c48d8b04SBranden Bonaby
104c48d8b04SBranden Bonaby# Get the state location
105c48d8b04SBranden Bonabydef locate_state(device, file_map):
106c48d8b04SBranden Bonaby        return file_map[device][f_names.state_f.value]
107c48d8b04SBranden Bonaby
108c48d8b04SBranden Bonaby# Validate delay values to make sure they are acceptable to
109c48d8b04SBranden Bonaby# enable delays on a device
110c48d8b04SBranden Bonabydef validate_delay_values(delay):
111c48d8b04SBranden Bonaby
112c48d8b04SBranden Bonaby        if (delay[0]  == -1 and delay[1] == -1):
113c48d8b04SBranden Bonaby                print("\nError, At least 1 value must be greater than 0")
114c48d8b04SBranden Bonaby                exit(-1)
115c48d8b04SBranden Bonaby        for i in delay:
116c48d8b04SBranden Bonaby                if (i < -1 or i == 0 or i > 1000):
117c48d8b04SBranden Bonaby                        print("\nError, Values must be  equal to -1 "
118c48d8b04SBranden Bonaby                              "or be > 0 and <= 1000")
119c48d8b04SBranden Bonaby                        exit(-1)
120c48d8b04SBranden Bonaby
121c48d8b04SBranden Bonaby# Validate argument path
122c48d8b04SBranden Bonabydef validate_args_path(path, arg_set, file_map):
123c48d8b04SBranden Bonaby
124c48d8b04SBranden Bonaby        if (not path and any(element in arg_set for element in single_actions)):
125c48d8b04SBranden Bonaby                print("Error, path (-p) REQUIRED for the specified option. "
126c48d8b04SBranden Bonaby                      "Use (-h) to check usage.")
127c48d8b04SBranden Bonaby                exit(-1)
128c48d8b04SBranden Bonaby        elif (path and any(item in arg_set for item in all_actions)):
129c48d8b04SBranden Bonaby                print("Error, path (-p) NOT REQUIRED for the specified option. "
130c48d8b04SBranden Bonaby                      "Use (-h) to check usage." )
131c48d8b04SBranden Bonaby                exit(-1)
132c48d8b04SBranden Bonaby        elif (path not in file_map and any(item in arg_set
133c48d8b04SBranden Bonaby                                           for item in single_actions)):
134c48d8b04SBranden Bonaby                print("Error, path '{}' not a valid vmbus device".format(path))
135c48d8b04SBranden Bonaby                exit(-1)
136c48d8b04SBranden Bonaby
137c48d8b04SBranden Bonaby# display Testing status of single device
138c48d8b04SBranden Bonabydef get_device_test_values(path, file_map):
139c48d8b04SBranden Bonaby
140c48d8b04SBranden Bonaby        for name in file_map[path]:
141c48d8b04SBranden Bonaby                file_location = file_map[path][name]
142c48d8b04SBranden Bonaby                print( name + " = " + str(read_test_files(file_location)))
143c48d8b04SBranden Bonaby
144c48d8b04SBranden Bonaby# Create a map of the vmbus devices and their associated files
145c48d8b04SBranden Bonaby# [key=device, value = [key = filename, value = file path]]
146c48d8b04SBranden Bonabydef recursive_file_lookup(path, file_map):
147c48d8b04SBranden Bonaby
148c48d8b04SBranden Bonaby        for f_path in glob.iglob(path + '**/*'):
149c48d8b04SBranden Bonaby                if (os.path.isfile(f_path)):
150c48d8b04SBranden Bonaby                        if (f_path.rsplit("/",2)[0] == debugfs_hyperv_path):
151c48d8b04SBranden Bonaby                                directory = f_path.rsplit("/",1)[0]
152c48d8b04SBranden Bonaby                        else:
153c48d8b04SBranden Bonaby                                directory = f_path.rsplit("/",2)[0]
154c48d8b04SBranden Bonaby                        f_name = f_path.split("/")[-1]
155c48d8b04SBranden Bonaby                        if (file_map.get(directory)):
156c48d8b04SBranden Bonaby                                file_map[directory].update({f_name:f_path})
157c48d8b04SBranden Bonaby                        else:
158c48d8b04SBranden Bonaby                                file_map[directory] = {f_name:f_path}
159c48d8b04SBranden Bonaby                elif (os.path.isdir(f_path)):
160c48d8b04SBranden Bonaby                        recursive_file_lookup(f_path,file_map)
161c48d8b04SBranden Bonaby        return file_map
162c48d8b04SBranden Bonaby
163c48d8b04SBranden Bonaby# display Testing state of devices
164c48d8b04SBranden Bonabydef get_all_devices_test_status(file_map):
165c48d8b04SBranden Bonaby
166c48d8b04SBranden Bonaby        for device in file_map:
167*ed0cf84eSAni Sinha                if (get_test_state(locate_state(device, file_map)) == 1):
168c48d8b04SBranden Bonaby                        print("Testing = ON for: {}"
169c48d8b04SBranden Bonaby                              .format(device.split("/")[5]))
170c48d8b04SBranden Bonaby                else:
171c48d8b04SBranden Bonaby                        print("Testing = OFF for: {}"
172c48d8b04SBranden Bonaby                              .format(device.split("/")[5]))
173c48d8b04SBranden Bonaby
174c48d8b04SBranden Bonaby# read the vmbus device files, path must be absolute path before calling
175c48d8b04SBranden Bonabydef read_test_files(path):
176c48d8b04SBranden Bonaby        try:
177c48d8b04SBranden Bonaby                with open(path,"r") as f:
178c48d8b04SBranden Bonaby                        file_value = f.readline().strip()
179c48d8b04SBranden Bonaby                return int(file_value)
180c48d8b04SBranden Bonaby
181c48d8b04SBranden Bonaby        except IOError as e:
182c48d8b04SBranden Bonaby                errno, strerror = e.args
183c48d8b04SBranden Bonaby                print("I/O error({0}): {1} on file {2}"
184c48d8b04SBranden Bonaby                      .format(errno, strerror, path))
185c48d8b04SBranden Bonaby                exit(-1)
186c48d8b04SBranden Bonaby        except ValueError:
187c48d8b04SBranden Bonaby                print ("Element to int conversion error in: \n{}".format(path))
188c48d8b04SBranden Bonaby                exit(-1)
189c48d8b04SBranden Bonaby
190c48d8b04SBranden Bonaby# writing to vmbus device files, path must be absolute path before calling
191c48d8b04SBranden Bonabydef write_test_files(path, value):
192c48d8b04SBranden Bonaby
193c48d8b04SBranden Bonaby        try:
194c48d8b04SBranden Bonaby                with open(path,"w") as f:
195c48d8b04SBranden Bonaby                        f.write("{}".format(value))
196c48d8b04SBranden Bonaby        except IOError as e:
197c48d8b04SBranden Bonaby                errno, strerror = e.args
198c48d8b04SBranden Bonaby                print("I/O error({0}): {1} on file {2}"
199c48d8b04SBranden Bonaby                      .format(errno, strerror, path))
200c48d8b04SBranden Bonaby                exit(-1)
201c48d8b04SBranden Bonaby
202c48d8b04SBranden Bonaby# set testing state of device
203c48d8b04SBranden Bonabydef set_test_state(state_path, state_value, quiet):
204c48d8b04SBranden Bonaby
205c48d8b04SBranden Bonaby        write_test_files(state_path, state_value)
206*ed0cf84eSAni Sinha        if (get_test_state(state_path) == 1):
207c48d8b04SBranden Bonaby                if (not quiet):
208c48d8b04SBranden Bonaby                        print("Testing = ON for device: {}"
209c48d8b04SBranden Bonaby                              .format(state_path.split("/")[5]))
210c48d8b04SBranden Bonaby        else:
211c48d8b04SBranden Bonaby                if (not quiet):
212c48d8b04SBranden Bonaby                        print("Testing = OFF for device: {}"
213c48d8b04SBranden Bonaby                              .format(state_path.split("/")[5]))
214c48d8b04SBranden Bonaby
215c48d8b04SBranden Bonaby# get testing state of device
216c48d8b04SBranden Bonabydef get_test_state(state_path):
217c48d8b04SBranden Bonaby        #state == 1 - test = ON
218c48d8b04SBranden Bonaby        #state == 0 - test = OFF
219c48d8b04SBranden Bonaby        return  read_test_files(state_path)
220c48d8b04SBranden Bonaby
221c48d8b04SBranden Bonaby# write 1 - 1000 microseconds, into a single device using the
222c48d8b04SBranden Bonaby# fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay
223c48d8b04SBranden Bonaby# debugfs attributes
224c48d8b04SBranden Bonabydef set_delay_values(device, file_map, delay_length, quiet):
225c48d8b04SBranden Bonaby
226c48d8b04SBranden Bonaby        try:
227c48d8b04SBranden Bonaby                interrupt = file_map[device][f_names.buff_f.value]
228c48d8b04SBranden Bonaby                message = file_map[device][f_names.mess_f.value]
229c48d8b04SBranden Bonaby
230c48d8b04SBranden Bonaby                # delay[0]- buffer interrupt delay, delay[1]- message delay
231c48d8b04SBranden Bonaby                if (delay_length[0] >= 0 and delay_length[0] <= 1000):
232c48d8b04SBranden Bonaby                        write_test_files(interrupt, delay_length[0])
233c48d8b04SBranden Bonaby                if (delay_length[1] >= 0 and delay_length[1] <= 1000):
234c48d8b04SBranden Bonaby                        write_test_files(message, delay_length[1])
235c48d8b04SBranden Bonaby                if (not quiet):
236c48d8b04SBranden Bonaby                        print("Buffer delay testing = {} for: {}"
237c48d8b04SBranden Bonaby                              .format(read_test_files(interrupt),
238c48d8b04SBranden Bonaby                                      interrupt.split("/")[5]))
239c48d8b04SBranden Bonaby                        print("Message delay testing = {} for: {}"
240c48d8b04SBranden Bonaby                              .format(read_test_files(message),
241c48d8b04SBranden Bonaby                                      message.split("/")[5]))
242c48d8b04SBranden Bonaby        except IOError as e:
243c48d8b04SBranden Bonaby                errno, strerror = e.args
244c48d8b04SBranden Bonaby                print("I/O error({0}): {1} on files {2}{3}"
245c48d8b04SBranden Bonaby                      .format(errno, strerror, interrupt, message))
246c48d8b04SBranden Bonaby                exit(-1)
247c48d8b04SBranden Bonaby
248c48d8b04SBranden Bonaby# enabling delay testing on all devices
249c48d8b04SBranden Bonabydef set_delay_all_devices(file_map, delay, quiet):
250c48d8b04SBranden Bonaby
251c48d8b04SBranden Bonaby        for device in (file_map):
252c48d8b04SBranden Bonaby                set_test_state(locate_state(device, file_map),
253c48d8b04SBranden Bonaby                               dev_state.on.value,
254c48d8b04SBranden Bonaby                               quiet)
255c48d8b04SBranden Bonaby                set_delay_values(device, file_map, delay, quiet)
256c48d8b04SBranden Bonaby
257c48d8b04SBranden Bonaby# disable all testing on a SINGLE device.
258c48d8b04SBranden Bonabydef disable_testing_single_device(device, file_map):
259c48d8b04SBranden Bonaby
260c48d8b04SBranden Bonaby        for name in file_map[device]:
261c48d8b04SBranden Bonaby                file_location = file_map[device][name]
262c48d8b04SBranden Bonaby                write_test_files(file_location, dev_state.off.value)
263c48d8b04SBranden Bonaby        print("ALL testing now OFF for {}".format(device.split("/")[-1]))
264c48d8b04SBranden Bonaby
265c48d8b04SBranden Bonaby# disable all testing on ALL devices
266c48d8b04SBranden Bonabydef disable_all_testing(file_map):
267c48d8b04SBranden Bonaby
268c48d8b04SBranden Bonaby        for device in file_map:
269c48d8b04SBranden Bonaby                disable_testing_single_device(device, file_map)
270c48d8b04SBranden Bonaby
271c48d8b04SBranden Bonabydef parse_args():
272c48d8b04SBranden Bonaby        parser = argparse.ArgumentParser(prog = "vmbus_testing",usage ="\n"
273c48d8b04SBranden Bonaby                "%(prog)s [delay]   [-h] [-e|-E] -t [-p]\n"
274c48d8b04SBranden Bonaby                "%(prog)s [view_all       | V]      [-h]\n"
275c48d8b04SBranden Bonaby                "%(prog)s [disable_all    | D]      [-h]\n"
276c48d8b04SBranden Bonaby                "%(prog)s [disable_single | d]      [-h|-p]\n"
277c48d8b04SBranden Bonaby                "%(prog)s [view_single    | v]      [-h|-p]\n"
278c48d8b04SBranden Bonaby                "%(prog)s --version\n",
279c48d8b04SBranden Bonaby                description = "\nUse lsvmbus to get vmbus device type "
280c48d8b04SBranden Bonaby                "information.\n" "\nThe debugfs root path is "
281c48d8b04SBranden Bonaby                "/sys/kernel/debug/hyperv",
282c48d8b04SBranden Bonaby                formatter_class = RawDescriptionHelpFormatter)
283c48d8b04SBranden Bonaby        subparsers = parser.add_subparsers(dest = "action")
284c48d8b04SBranden Bonaby        parser.add_argument("--version", action = "version",
285c48d8b04SBranden Bonaby                version = '%(prog)s 0.1.0')
286c48d8b04SBranden Bonaby        parser.add_argument("-q","--quiet", action = "store_true",
287c48d8b04SBranden Bonaby                help = "silence none important test messages."
288c48d8b04SBranden Bonaby                       " This will only work when enabling testing"
289c48d8b04SBranden Bonaby                       " on a device.")
290c48d8b04SBranden Bonaby        # Use the path parser to hold the --path attribute so it can
291c48d8b04SBranden Bonaby        # be shared between subparsers. Also do the same for the state
292c48d8b04SBranden Bonaby        # parser, as all testing methods will use --enable_all and
293c48d8b04SBranden Bonaby        # enable_single.
294c48d8b04SBranden Bonaby        path_parser = argparse.ArgumentParser(add_help=False)
295c48d8b04SBranden Bonaby        path_parser.add_argument("-p","--path", metavar = "",
296c48d8b04SBranden Bonaby                help = "Debugfs path to a vmbus device. The path "
297c48d8b04SBranden Bonaby                "must be the absolute path to the device.")
298c48d8b04SBranden Bonaby        state_parser = argparse.ArgumentParser(add_help=False)
299c48d8b04SBranden Bonaby        state_group = state_parser.add_mutually_exclusive_group(required = True)
300c48d8b04SBranden Bonaby        state_group.add_argument("-E", "--enable_all", action = "store_const",
301c48d8b04SBranden Bonaby                                 const = "enable_all",
302c48d8b04SBranden Bonaby                                 help = "Enable the specified test type "
303c48d8b04SBranden Bonaby                                 "on ALL vmbus devices.")
304c48d8b04SBranden Bonaby        state_group.add_argument("-e", "--enable_single",
305c48d8b04SBranden Bonaby                                 action = "store_const",
306c48d8b04SBranden Bonaby                                 const = "enable_single",
307c48d8b04SBranden Bonaby                                 help = "Enable the specified test type on a "
308c48d8b04SBranden Bonaby                                 "SINGLE vmbus device.")
309c48d8b04SBranden Bonaby        parser_delay = subparsers.add_parser("delay",
310c48d8b04SBranden Bonaby                        parents = [state_parser, path_parser],
311c48d8b04SBranden Bonaby                        help = "Delay the ring buffer interrupt or the "
312c48d8b04SBranden Bonaby                        "ring buffer message reads in microseconds.",
313c48d8b04SBranden Bonaby                        prog = "vmbus_testing",
314c48d8b04SBranden Bonaby                        usage = "%(prog)s [-h]\n"
315c48d8b04SBranden Bonaby                        "%(prog)s -E -t [value] [value]\n"
316c48d8b04SBranden Bonaby                        "%(prog)s -e -t [value] [value] -p",
317c48d8b04SBranden Bonaby                        description = "Delay the ring buffer interrupt for "
318c48d8b04SBranden Bonaby                        "vmbus devices, or delay the ring buffer message "
319c48d8b04SBranden Bonaby                        "reads for vmbus devices (both in microseconds). This "
320c48d8b04SBranden Bonaby                        "is only on the host to guest channel.")
321c48d8b04SBranden Bonaby        parser_delay.add_argument("-t", "--delay_time", metavar = "", nargs = 2,
322c48d8b04SBranden Bonaby                        type = check_range, default =[0,0], required = (True),
323c48d8b04SBranden Bonaby                        help = "Set [buffer] & [message] delay time. "
324c48d8b04SBranden Bonaby                        "Value constraints: -1 == value "
325c48d8b04SBranden Bonaby                        "or 0 < value <= 1000.\n"
326c48d8b04SBranden Bonaby                        "Use -1 to keep the previous value for that delay "
327c48d8b04SBranden Bonaby                        "type, or a value > 0 <= 1000 to change the delay "
328c48d8b04SBranden Bonaby                        "time.")
329c48d8b04SBranden Bonaby        parser_dis_all = subparsers.add_parser("disable_all",
330c48d8b04SBranden Bonaby                        aliases = ['D'], prog = "vmbus_testing",
331c48d8b04SBranden Bonaby                        usage = "%(prog)s [disable_all | D] -h\n"
332c48d8b04SBranden Bonaby                        "%(prog)s [disable_all | D]\n",
333c48d8b04SBranden Bonaby                        help = "Disable ALL testing on ALL vmbus devices.",
334c48d8b04SBranden Bonaby                        description = "Disable ALL testing on ALL vmbus "
335c48d8b04SBranden Bonaby                        "devices.")
336c48d8b04SBranden Bonaby        parser_dis_single = subparsers.add_parser("disable_single",
337c48d8b04SBranden Bonaby                        aliases = ['d'],
338c48d8b04SBranden Bonaby                        parents = [path_parser], prog = "vmbus_testing",
339c48d8b04SBranden Bonaby                        usage = "%(prog)s [disable_single | d] -h\n"
340c48d8b04SBranden Bonaby                        "%(prog)s [disable_single | d] -p\n",
341c48d8b04SBranden Bonaby                        help = "Disable ALL testing on a SINGLE vmbus device.",
342c48d8b04SBranden Bonaby                        description = "Disable ALL testing on a SINGLE vmbus "
343c48d8b04SBranden Bonaby                        "device.")
344c48d8b04SBranden Bonaby        parser_view_all = subparsers.add_parser("view_all", aliases = ['V'],
345c48d8b04SBranden Bonaby                        help = "View the test state for ALL vmbus devices.",
346c48d8b04SBranden Bonaby                        prog = "vmbus_testing",
347c48d8b04SBranden Bonaby                        usage = "%(prog)s [view_all | V] -h\n"
348c48d8b04SBranden Bonaby                        "%(prog)s [view_all | V]\n",
349c48d8b04SBranden Bonaby                        description = "This shows the test state for ALL the "
350c48d8b04SBranden Bonaby                        "vmbus devices.")
351c48d8b04SBranden Bonaby        parser_view_single = subparsers.add_parser("view_single",
352c48d8b04SBranden Bonaby                        aliases = ['v'],parents = [path_parser],
353c48d8b04SBranden Bonaby                        help = "View the test values for a SINGLE vmbus "
354c48d8b04SBranden Bonaby                        "device.",
355c48d8b04SBranden Bonaby                        description = "This shows the test values for a SINGLE "
356c48d8b04SBranden Bonaby                        "vmbus device.", prog = "vmbus_testing",
357c48d8b04SBranden Bonaby                        usage = "%(prog)s [view_single | v] -h\n"
358c48d8b04SBranden Bonaby                        "%(prog)s [view_single | v] -p")
359c48d8b04SBranden Bonaby
360c48d8b04SBranden Bonaby        return  parser.parse_args()
361c48d8b04SBranden Bonaby
362c48d8b04SBranden Bonaby# value checking for range checking input in parser
363c48d8b04SBranden Bonabydef check_range(arg1):
364c48d8b04SBranden Bonaby
365c48d8b04SBranden Bonaby        try:
366c48d8b04SBranden Bonaby                val = int(arg1)
367c48d8b04SBranden Bonaby        except ValueError as err:
368c48d8b04SBranden Bonaby                raise argparse.ArgumentTypeError(str(err))
369c48d8b04SBranden Bonaby        if val < -1 or val > 1000:
370c48d8b04SBranden Bonaby                message = ("\n\nvalue must be -1 or  0 < value <= 1000. "
371c48d8b04SBranden Bonaby                           "Value program received: {}\n").format(val)
372c48d8b04SBranden Bonaby                raise argparse.ArgumentTypeError(message)
373c48d8b04SBranden Bonaby        return val
374c48d8b04SBranden Bonaby
375c48d8b04SBranden Bonabyif __name__ == "__main__":
376c48d8b04SBranden Bonaby        main()
377