xref: /openbmc/openbmc-test-automation/lib/gen_plug_in.py (revision d0fd8838ea51df528b7c6f658b40b180eab35bd5)
1#!/usr/bin/env python
2
3r"""
4This module provides functions which are useful for running plug-ins.
5"""
6
7import sys
8import os
9import commands
10import glob
11
12import gen_print as gp
13import gen_misc as gm
14
15# Some help text that is common to more than one program.
16plug_in_dir_paths_help_text = \
17    'This is a colon-separated list of plug-in directory paths.  If one' +\
18    ' of the entries in the list is a plain directory name (i.e. no' +\
19    ' path info), it will be taken to be a native plug-in.  In that case,' +\
20    ' %(prog)s will search for the native plug-in in the "plug-ins"' +\
21    ' subdirectory of each path in the PATH environment variable until it' +\
22    ' is found.  Also, integrated plug-ins will automatically be appended' +\
23    ' to your plug_in_dir_paths list.  An integrated plug-in is any plug-in' +\
24    ' found using the PATH variable that contains a file named "integrated".'
25
26mch_class_help_text = \
27    'The class of machine that we are testing (e.g. "op" = "open power",' +\
28    ' "obmc" = "open bmc", etc).'
29
30PATH_LIST = gm.return_path_list()
31
32
33###############################################################################
34def get_plug_in_base_paths():
35
36    r"""
37    Get plug-in base paths and return them as a list.
38
39    This function searches the PATH_LIST (created from PATH environment
40    variable) for any paths that have a "plug_ins" subdirectory.  All such
41    paths are considered plug_in_base paths.
42    """
43
44    global PATH_LIST
45
46    plug_in_base_path_list = []
47
48    for path in PATH_LIST:
49        candidate_plug_in_base_path = path + "plug_ins/"
50        if os.path.isdir(candidate_plug_in_base_path):
51            plug_in_base_path_list.append(candidate_plug_in_base_path)
52
53    return plug_in_base_path_list
54
55###############################################################################
56# Define global plug_in_base_path_list and call get_plug_in_base_paths to set
57# its value.
58plug_in_base_path_list = get_plug_in_base_paths()
59
60
61###############################################################################
62def find_plug_in_package(plug_in_name):
63
64    r"""
65    Find and return the normalized directory path of the specified plug in.
66    This is done by searching the global plug_in_base_path_list.
67
68    Description of arguments:
69    plug_in_name                    The unqualified name of the plug-in
70                                    package.
71    """
72
73    global plug_in_base_path_list
74    for plug_in_base_dir_path in plug_in_base_path_list:
75        candidate_plug_in_dir_path = os.path.normpath(plug_in_base_dir_path +
76                                                      plug_in_name) + \
77                                                      os.sep
78        if os.path.isdir(candidate_plug_in_dir_path):
79            return candidate_plug_in_dir_path
80
81    return ""
82
83###############################################################################
84
85
86###############################################################################
87def validate_plug_in_package(plug_in_dir_path,
88                             mch_class="obmc"):
89
90    r"""
91    Validate the plug in package and return the normalized plug-in directory
92    path.
93
94    Description of arguments:
95    plug_in_dir_path                The "relative" or absolute path to a plug
96                                    in package directory.
97    mch_class                       The class of machine that we are testing
98                                    (e.g. "op" = "open power", "obmc" = "open
99                                    bmc", etc).
100    """
101
102    gp.dprint_executing()
103
104    if os.path.isabs(plug_in_dir_path):
105        # plug_in_dir_path begins with a slash so it is an absolute path.
106        candidate_plug_in_dir_path = os.path.normpath(plug_in_dir_path) +\
107                                     os.sep
108        if not os.path.isdir(candidate_plug_in_dir_path):
109            gp.print_error_report("Plug-in directory path \"" +
110                                  plug_in_dir_path + "\" does not exist.\n")
111            exit(1)
112    else:
113        # The plug_in_dir_path is actually a simple name (e.g.
114        # "OBMC_Sample")...
115        candidate_plug_in_dir_path = find_plug_in_package(plug_in_dir_path)
116        if candidate_plug_in_dir_path == "":
117            global PATH_LIST
118            gp.print_error_report("Plug-in directory path \"" +
119                                  plug_in_dir_path + "\" could not be found" +
120                                  " in any of the following directories:\n" +
121                                  gp.sprint_var(PATH_LIST))
122            exit(1)
123    # Make sure that this plug-in supports us...
124    supports_file_path = candidate_plug_in_dir_path + "supports_" + mch_class
125    if not os.path.exists(supports_file_path):
126        gp.print_error_report("The following file path could not be" +
127                              " found:\n" +
128                              gp.sprint_varx("supports_file_path",
129                                             supports_file_path) +
130                              "\nThis file is necessary to indicate that" +
131                              " the given plug-in supports the class of" +
132                              " machine we are testing, namely \"" +
133                              mch_class + "\".\n")
134        exit(1)
135
136    return candidate_plug_in_dir_path
137
138###############################################################################
139
140
141###############################################################################
142def return_integrated_plug_ins(mch_class="obmc"):
143
144    r"""
145    Return a list of integrated plug-ins.  Integrated plug-ins are plug-ins
146    which are selected without regard for whether the user has specified them.
147    In other words, they are "integrated" into the program suite.  The
148    programmer designates a plug-in as integrated by putting a file named
149    "integrated" into the plug-in package directory.
150
151    Description of arguments:
152    mch_class                       The class of machine that we are testing
153                                    (e.g. "op" = "open power", "obmc" = "open
154                                    bmc", etc).
155    """
156
157    global plug_in_base_path_list
158
159    integrated_plug_ins_list = []
160
161    for plug_in_base_path in plug_in_base_path_list:
162        # Get a list of all plug-in paths that support our mch_class.
163        mch_class_candidate_list = glob.glob(plug_in_base_path +
164                                             "*/supports_" + mch_class)
165        for candidate_path in mch_class_candidate_list:
166            integrated_plug_in_dir_path = os.path.dirname(candidate_path) +\
167                                          os.sep
168            integrated_file_path = integrated_plug_in_dir_path + "integrated"
169            if os.path.exists(integrated_file_path):
170                plug_in_name = \
171                    os.path.basename(os.path.dirname(candidate_path))
172                if plug_in_name not in integrated_plug_ins_list:
173                    # If this plug-in has not already been added to the list...
174                    integrated_plug_ins_list.append(plug_in_name)
175
176    return integrated_plug_ins_list
177
178###############################################################################
179
180
181###############################################################################
182def return_plug_in_packages_list(plug_in_dir_paths,
183                                 mch_class="obmc"):
184
185    r"""
186    Return a list of plug-in packages given the plug_in_dir_paths string.
187    This function calls validate_plug_in_package so it will fail if
188    plug_in_dir_paths contains any invalid plug-ins.
189
190    Description of arguments:
191    plug_in_dir_path                The "relative" or absolute path to a plug
192                                    in package directory.
193    mch_class                       The class of machine that we are testing
194                                    (e.g. "op" = "open power", "obmc" = "open
195                                    bmc", etc).
196    """
197
198    if plug_in_dir_paths != "":
199        plug_in_packages_list = plug_in_dir_paths.split(":")
200    else:
201        plug_in_packages_list = []
202
203    # Get a list of integrated plug-ins (w/o full path names).
204    integrated_plug_ins_list = return_integrated_plug_ins(mch_class)
205    # Put both lists together in plug_in_packages_list with no duplicates.
206    # NOTE: This won't catch duplicates if the caller specifies the full path
207    # name of a native plug-in but that should be rare enough.
208
209    plug_in_packages_list = plug_in_packages_list + integrated_plug_ins_list
210
211    plug_in_packages_list = \
212        list(set([validate_plug_in_package(path, mch_class)
213                  for path in plug_in_packages_list]))
214
215    return plug_in_packages_list
216
217###############################################################################
218