Пример #1
0
 def __init__(self, input_path, liberty_path, lef_path, def_path):
     self.input_path = input_path
     self.liberty_path = liberty_path
     self.lef_path = lef_path
     self.def_path = def_path
     self.pathFile = PathParser(self.input_path)
     self.lefFile = LefParser(self.lef_path)
     self.defFile = DefParser(self.def_path)
     self.liberty_file = open(self.liberty_path).read()
     self.library = parse_liberty(self.liberty_file)
     self.SCALE = 0
     self.CELL_HEIGHT = 0
Пример #2
0
    def parse(self, filename):
        svg = Svg()
        doc = xml.dom.minidom.parse(filename)       
        path_tags = doc.getElementsByTagName('path')
        parser = PathParser()
        for path_tag in path_tags:
            id, path = parser.parse(path_tag)
            svg.add_path(id, path)

        x, y = svg.get_boundary().get_centroid()
        for path in svg.paths.values():
            path.offset(-x, -y)
        return svg
Пример #3
0
class testPathParser(unittest.TestCase):

    def setUp(self):
        self.path_parser = PathParser()
        # For test_parser_root()
        self.test_html_root = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
           <title>Index of /pvt/mozilla.org/b2gotoro/nightly</title>
         </head>
         <body>
         <h1>Index of /pvt/mozilla.org/b2gotoro/nightly</h1>
         <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
         <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-aurora-hamachi-eng/">mozilla-aurora-hamachi-eng/</a></td><td align="right">03-Apr-2014 00:44  </td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-central-nexus-4-eng/">mozilla-central-nexus-4-eng/</a></td><td align="right">03-Apr-2014 00:56  </td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><th colspan="5"><hr></th></tr>
         </table>
         </body>
        </html>
        """
        self.expect_result_root = {'nexus-4': {'central': {'Engineer': {'src': 'mozilla-central-nexus-4-eng', 'last_modify_time': '03-Apr-2014 00:56'}}},
                              'hamachi': {'aurora': {'Engineer': {'src': 'mozilla-aurora-hamachi-eng', 'last_modify_time': '03-Apr-2014 00:44'}}}}
        # For test_parser_packages_gaia_gecko()
        self.test_html_packages_src_gaia_gecko = 'mozilla-central-hamachi-eng'
        self.test_html_packages_gaia_gecko = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
          <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</title>
         </head>
         <body>
        <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</h1>
        <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
        <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 21M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">5.9K</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 51M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 12K</td><td>&nbsp;</td></tr>
        <tr><th colspan="5"><hr></th></tr>
        </table>
        </body></html>
        """
        self.expect_result_packages_gaia_gecko = {'gaia': 'gaia.zip', 'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'}
        # For test_parser_packages_all()
        self.test_html_packages_src_all = 'mozilla-central-nexus-4-eng'
        self.test_html_packages_all = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
          <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</title>
         </head>
         <body>
        <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</h1>
        <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
        <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 20M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">2.4K</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 58M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="nexus-4.zip">nexus-4.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">141M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 17K</td><td>&nbsp;</td></tr>
        <tr><th colspan="5"><hr></th></tr>
        </table>
        </body></html>
        """
        self.expect_result_packages_all = {'images': 'nexus-4.zip', 'gaia': 'gaia.zip', 'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'}

    def test_parser_root(self):
        '''
        Test parsing the HTML page which contains the builds list.
        '''
        result = self.path_parser._parse_device_version_and_time_from_list(self.path_parser._parse_build_and_time_from_html(self.test_html_root))
        self.assertEqual(result, self.expect_result_root)

    def test_parser_packages_gaia_gecko(self):
        '''
        Test parsing the gaia/gecko from Builds page.
        '''
        result = self.path_parser._parse_available_packages(self.test_html_packages_src_gaia_gecko, self.test_html_packages_gaia_gecko)
        self.assertEqual(result, self.expect_result_packages_gaia_gecko)

    def test_parser_packages_all(self):
        '''
        Test parsing the gaia/gecko/images from Builds page.
        '''
        result = self.path_parser._parse_available_packages(self.test_html_packages_src_all, self.test_html_packages_all)
        self.assertEqual(result, self.expect_result_packages_all)

    def test_verify_build_id(self):
        '''
        Test verifying the build id.
        '''
        self.assertTrue(self.path_parser._verify_build_id('20140408160201'))
        self.assertTrue(self.path_parser._verify_build_id('2014-04-08-16-02-01'))
        self.assertFalse(self.path_parser._verify_build_id('2014-04-08-16-02-01-0000'))
        self.assertFalse(self.path_parser._verify_build_id('This is not build id'))

    def test_get_path_of_build_id(self):
        '''
        Test the build id translation.
        '''
        self.assertEqual('/2014/04/2014-04-08-16-02-01/', self.path_parser._get_path_of_build_id('2014-04-08-16-02-01'))
        self.assertEqual('/2014/04/2014-04-13-16-02-02/', self.path_parser._get_path_of_build_id('2014-04-13-16-02-02'))
Пример #4
0
 def setUp(self):
     self.path_parser = PathParser()
     # For test_parser_root()
     self.test_html_root = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
        <title>Index of /pvt/mozilla.org/b2gotoro/nightly</title>
      </head>
      <body>
      <h1>Index of /pvt/mozilla.org/b2gotoro/nightly</h1>
      <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
      <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-aurora-hamachi-eng/">mozilla-aurora-hamachi-eng/</a></td><td align="right">03-Apr-2014 00:44  </td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-central-nexus-4-eng/">mozilla-central-nexus-4-eng/</a></td><td align="right">03-Apr-2014 00:56  </td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><th colspan="5"><hr></th></tr>
      </table>
      </body>
     </html>
     """
     self.expect_result_root = {'nexus-4': {'central': {'Engineer': {'src': 'mozilla-central-nexus-4-eng', 'last_modify_time': '03-Apr-2014 00:56'}}},
                           'hamachi': {'aurora': {'Engineer': {'src': 'mozilla-aurora-hamachi-eng', 'last_modify_time': '03-Apr-2014 00:44'}}}}
     # For test_parser_packages_gaia_gecko()
     self.test_html_packages_src_gaia_gecko = 'mozilla-central-hamachi-eng'
     self.test_html_packages_gaia_gecko = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
       <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</title>
      </head>
      <body>
     <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</h1>
     <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
     <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 21M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">5.9K</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 51M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 12K</td><td>&nbsp;</td></tr>
     <tr><th colspan="5"><hr></th></tr>
     </table>
     </body></html>
     """
     self.expect_result_packages_gaia_gecko = {'gaia': 'gaia.zip', 'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'}
     # For test_parser_packages_all()
     self.test_html_packages_src_all = 'mozilla-central-nexus-4-eng'
     self.test_html_packages_all = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
       <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</title>
      </head>
      <body>
     <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</h1>
     <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
     <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 20M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">2.4K</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 58M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="nexus-4.zip">nexus-4.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">141M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 17K</td><td>&nbsp;</td></tr>
     <tr><th colspan="5"><hr></th></tr>
     </table>
     </body></html>
     """
     self.expect_result_packages_all = {'images': 'nexus-4.zip', 'gaia': 'gaia.zip', 'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'}
Пример #5
0
class Main:
    def __init__(self, input_path, liberty_path, lef_path, def_path):
        self.input_path = input_path
        self.liberty_path = liberty_path
        self.lef_path = lef_path
        self.def_path = def_path
        self.pathFile = PathParser(self.input_path)
        self.lefFile = LefParser(self.lef_path)
        self.defFile = DefParser(self.def_path)
        self.liberty_file = open(self.liberty_path).read()
        self.library = parse_liberty(self.liberty_file)
        self.SCALE = 0
        self.CELL_HEIGHT = 0

    def parse_files(self):
        self.pathFile.parse_user_file()
        self.lefFile.parse()
        self.defFile.parse()
        self.SCALE = float(self.defFile.scale)
        self.CELL_HEIGHT = self.scale_dimension(self.lefFile.cell_height)

    def run(self):
        self.parse_files()
        self.check_path_continuity()
        self.get_worst_delay()

    def get_worst_delay(self):
        fall = self.get_path_delay('fall')
        rise = self.get_path_delay('rise')
        print("worst", max(fall, rise), "secs")

    def scale_dimension(self, dimension):
        return int(self.SCALE * dimension)

    def find_net_of_comp_pin(self, component, pin):
        for net in self.defFile.nets:
            for entry in net.comp_pin:
                if component == entry[0] and pin == entry[1]:
                    return net
        return -1

    def find_pin_location(self, pin_name):
        for pin in self.defFile.pins:
            if pin_name == pin.name:
                return pin.placed
        return -1

    def find_component_location(self, component_name):
        for component in self.defFile.components:
            if component_name == component.name:
                return component.placed
        return -1

    def check_path_continuity(self):
        path = self.pathFile.get_path()
        curr_node = path.nodeat(0)
        while curr_node is not None:
            # Get current point in the path
            point_one = curr_node.value
            curr_comp_macro = self.lefFile.macro_dict.get(point_one.get_component().split('_')[0])
            output_pin = Util.find_output_pin_name(curr_comp_macro.pin_dict)
            net = self.find_net_of_comp_pin(point_one.get_component(), output_pin)
            point_two = curr_node.next.value if curr_node.next is not None else None
            if point_two is not None:
                if not Util.point_is_in_net(point_two, net):
                    raise Exception("Path is discontinuous.")
            curr_node = curr_node.next

    def get_path_delay(self, unate):
        path = self.pathFile.get_path()
        curr_node = path.nodeat(0)
        total_delay = 0
        input_transition_time = 0
        while curr_node is not None:
            # Get current point in the path
            point_one = curr_node.value
            # Find the starting component/pin macro in the lef file
            curr_comp_macro = self.lefFile.macro_dict.get(point_one.get_component().split('_')[0])
            # Find the output pin name of the current from the macro
            output_pin = Util.find_output_pin_name(curr_comp_macro.pin_dict)
            # Get the center location of current component
            curr_comp_location = self.find_component_location(point_one.get_component())
            # Get the width of the current component
            curr_comp_width = self.scale_dimension(curr_comp_macro.info["SIZE"][0])
            # Determine the net of the current component's output pin
            net = self.find_net_of_comp_pin(point_one.get_component(), output_pin)
            # Get the next point in the path if not end of path else make none
            point_two = curr_node.next.value if curr_node.next is not None else None
            # Split logic based on end of path or not
            if point_two is not None and point_two.get_component() != point_one.get_component():
                # Get the macro of the next component from the lef file
                next_comp_macro = self.lefFile.macro_dict.get(point_two.get_component().split('_')[0])
                # Get the center location of the next component
                next_comp_location = self.find_component_location(point_two.get_component())
                # Get the width of the next component
                next_comp_width = self.scale_dimension(next_comp_macro.info["SIZE"][0])
                cell_delay, input_transition_time, unate, total_net_cap = \
                    self.calc_cells_delay(unate,
                                          input_transition_time,
                                          net.comp_pin,
                                          point_one.get_component(),
                                          point_one.get_pin(),
                                          output_pin)
                r_drive = cell_delay / total_net_cap
                interconnect_delay = self.cal_interconnect_delay(net.routed, curr_comp_location, curr_comp_width,
                                                                 next_comp_location,
                                                                 next_comp_width, r_drive)
                total_delay += cell_delay + interconnect_delay
            elif point_two is not None and point_two.get_component() == point_one.get_component():
                cell_delay, input_transition_time, unate, total_net_cap = self.calc_cells_delay(unate,
                                                                                                input_transition_time,
                                                                                                net.comp_pin,
                                                                                                point_one.get_component(),
                                                                                                point_one.get_pin(),
                                                                                                output_pin)
                total_delay += cell_delay

            curr_node = curr_node.next
        print(unate, total_delay, "secs")
        return total_delay

    def calc_cells_delay(self, unate, input_transition_time, cells, path_cell, input_pin, output_pin):
        """
        Calculates the delay of all the cells in the net
        :param unate: unate of input signal
        :param input_transition_time: input transition time of input signal
        :param cells: list of cells in the net with their pins
        :param path_cell: path cell as it is in DEF file
        :param input_pin: input pin name
        :param output_pin: output pin name
        :return: delay, output transition time, output unate
        """
        total_net_cap = 0
        for comp in cells:
            if comp[0] != path_cell and comp[0] not in self.defFile.pins:
                total_net_cap += self.get_pin_cap(comp[0].split('_')[0], comp[1])
        cell_delay, input_transition_time, unate = self.get_arc_cap_trans(path_cell.split('_')[0], input_pin,
                                                                          output_pin, unate, total_net_cap, input_transition_time)
        return cell_delay, input_transition_time, unate, total_net_cap

    def get_layer(self, layer_name):
        """
        Retrieves the layer object from LEF file
        :param layer_name: the name of the layer as it is in the LEF file
        :return: the layer object from the LEF file
        """
        return self.lefFile.layer_dict.get(layer_name)

    def cal_interconnect_delay(self, routes, curr_comp_location, curr_comp_width, next_comp_location, next_comp_width,
                               r_drive):
        # Continuity Check
        continuous_segments = [Segment()]
        seg_num = 0
        for route in routes:
            if continuous_segments[seg_num].check_continuity(route):
                continuous_segments[seg_num].add_route(route)
            else:
                continuous_segments.append(Segment())
                seg_num += 1
                continuous_segments[seg_num].add_route(route)
        # Main Path Check
        ll_rect_curr_comp = curr_comp_location
        ur_rect_curr_comp = (curr_comp_location[0] + curr_comp_width, curr_comp_location[1] + self.CELL_HEIGHT)
        ll_rect_next_comp = next_comp_location
        ur_rect_next_comp = (next_comp_location[0] + next_comp_width, next_comp_location[1] + self.CELL_HEIGHT)
        for segment in continuous_segments:
            terminal_points = segment.get_terminal_points()
            connects_comp = Util.in_rectangle(ll_rect_curr_comp, ur_rect_curr_comp,
                                              terminal_points[0]) and Util.in_rectangle(ll_rect_next_comp,
                                                                                        ur_rect_next_comp,
                                                                                        terminal_points[1])
            connects_comp_reverse = Util.in_rectangle(ll_rect_curr_comp, ur_rect_curr_comp,
                                                      terminal_points[1]) and Util.in_rectangle(
                ll_rect_next_comp, ur_rect_next_comp, terminal_points[0])
            if connects_comp or connects_comp_reverse:
                segment.set_type("MAIN")
        return self.cal_wire_delay(Segment.get_main_path(continuous_segments).get_routes(), r_drive)

    def cal_wire_delay(self, routes, r_drive):
        """
        Calculates the total delay from metal layer wires using Elmore's model
        :param routes: the routes to traverse
        :return: The delay of traversing these route in seconds
        """
        delay = 0
        for route in routes:
            if len(route.points) > 1:
                layer = self.get_layer(route.layer)
                length = Util.calc_length_segment(route) * 10 ** -3
                width = length * self.scale_dimension(layer.width) * 10 ** -3
                capacitance = (layer.capacitance[1] * 10 ** -12) * (length * width)
                resistance = layer.resistance[1] * (length / width)
                delay += r_drive * capacitance
                r_drive += resistance
        return delay

    def get_arc_cap_trans(self, cell_name, input_pin_name, output_pin_name, unate, total_net_capacitance,
                          input_transition):
        """
        Calculates the cell delay, output transition, and the output unate of a cell using NLDM from SCL
        :param cell_name: name of the cell as it is in the standard cell library
        :param input_pin_name: name of the input pin
        :param output_pin_name: name of the output pin
        :param unate: the current unate of the signal
        :param total_net_capacitance: the total capacitance in the net of the output pin
        :param input_transition: the output transition time of the previous cell
        :return: the delay in seconds, the output transition time of the current cell, the unate at output
        """
        clk_transition = 0.1
        sequential = (cell_name[0] == 'D')
        sequential_input_name = input_pin_name
        input_pin_name = 'CLK' if sequential else input_pin_name
        sequential_delay = 0
        if sequential:
            timings = self.library.get_group("cell", cell_name).get_group("pin", sequential_input_name).get_groups("timing")
            for timing in timings:
                unate_constraint = timing.get_group(unate + "_constraint")
                uc_index1, uc_index2, uc_values = Util.convert_to_float_arrays(unate_constraint.attributes["index_1"],
                                                                               unate_constraint.attributes["index_2"],
                                                                               unate_constraint.attributes["values"])
                sequential_delay += Util.interpolate(uc_index2, uc_index1, uc_values, clk_transition, input_transition)

        timings = self.library.get_group("cell", cell_name).get_group("pin", output_pin_name).get_groups("timing")
        input_transition = input_transition if not sequential else clk_transition
        for timing in timings:
            if timing.attributes["related_pin"] == input_pin_name:
                if timing.attributes["timing_sense"] == "non_unate":
                    delay_fall, output_transition_fall = self.get_cell_delay(timing, 'fall', total_net_capacitance,
                                                                             input_transition)
                    delay_rising, output_transition_rising = self.get_cell_delay(timing, 'rise', total_net_capacitance,
                                                                                 input_transition)
                    if delay_fall > delay_rising:
                        return delay_fall+sequential_delay, output_transition_fall, 'fall'
                    else:
                        return delay_rising+sequential_delay, output_transition_rising, 'rise'
                else:
                    unate = Util.determine_unate(timing.attributes["timing_sense"], unate)
                    delay, output_transition = self.get_cell_delay(timing, unate, total_net_capacitance,
                                                                   input_transition)
                    return delay+sequential_delay, output_transition, unate

    @staticmethod
    def get_cell_delay(timing, unate, total_net_capacitance, input_transition):
        cell_unate = timing.get_group("cell_" + unate)
        unate_transition = timing.get_group(unate + "_transition")
        cu_index1, cu_index2, cu_values = Util.convert_to_float_arrays(cell_unate.attributes["index_1"],
                                                                       cell_unate.attributes["index_2"],
                                                                       cell_unate.attributes["values"])
        ut_index1, ut_index2, ut_values = Util.convert_to_float_arrays(unate_transition.attributes["index_1"],
                                                                       unate_transition.attributes["index_2"],
                                                                       unate_transition.attributes["values"])
        delay = Util.interpolate(cu_index1, cu_index2, cu_values, total_net_capacitance, input_transition)
        output_transition = Util.interpolate(ut_index1, ut_index2, ut_values, total_net_capacitance,
                                             input_transition)
        return delay, output_transition

    def get_pin_cap(self, cell_name, pin_name, unate=None):
        """
        Retrieves the capacitance of a pin from the SCL
        :param cell_name: the name of the cell as it is in the SCL
        :param pin_name: the name of the pin
        :param unate: if None use worst, else use unate
        :return:
        """
        pin = self.library.get_group("cell", cell_name).get_group("pin", pin_name)
        return pin.attributes["capacitance"] if unate is None else pin.attributes[unate + "_capacitance"]

    def get_all_possible_paths(self):
        path = self.pathFile.get_path()
        starting_point = path.nodeat(0).value
        ending_point = path.nodeat(1).value

    @staticmethod
    def find_all_paths(self, graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return [path]
        if not graph.has_key(start):
            return []
        paths = []
        for node in graph[start]:
            if node not in path:
                newpaths = self.find_all_paths(graph, node, end, path)
                for newpath in newpaths:
                    paths.append(newpath)
        return paths
Пример #6
0
 def setUp(self):
     self.path_parser = PathParser()
     # For test_parser_root()
     self.test_html_root = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
        <title>Index of /pvt/mozilla.org/b2gotoro/nightly</title>
      </head>
      <body>
      <h1>Index of /pvt/mozilla.org/b2gotoro/nightly</h1>
      <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
      <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-aurora-hamachi-eng/">mozilla-aurora-hamachi-eng/</a></td><td align="right">03-Apr-2014 00:44  </td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-central-nexus-4-eng/">mozilla-central-nexus-4-eng/</a></td><td align="right">03-Apr-2014 00:56  </td><td align="right">  - </td><td>&nbsp;</td></tr>
      <tr><th colspan="5"><hr></th></tr>
      </table>
      </body>
     </html>
     """
     self.expect_result_root = {
         'nexus-4': {
             'central': {
                 'Engineer': {
                     'src': 'mozilla-central-nexus-4-eng',
                     'last_modify_time': '03-Apr-2014 00:56'
                 }
             }
         },
         'hamachi': {
             'aurora': {
                 'Engineer': {
                     'src': 'mozilla-aurora-hamachi-eng',
                     'last_modify_time': '03-Apr-2014 00:44'
                 }
             }
         }
     }
     # For test_parser_packages_gaia_gecko()
     self.test_html_packages_src_gaia_gecko = 'mozilla-central-hamachi-eng'
     self.test_html_packages_gaia_gecko = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
       <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</title>
      </head>
      <body>
     <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</h1>
     <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
     <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 21M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">5.9K</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 51M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 12K</td><td>&nbsp;</td></tr>
     <tr><th colspan="5"><hr></th></tr>
     </table>
     </body></html>
     """
     self.expect_result_packages_gaia_gecko = {
         'gaia': 'gaia.zip',
         'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'
     }
     # For test_parser_packages_all()
     self.test_html_packages_src_all = 'mozilla-central-nexus-4-eng'
     self.test_html_packages_all = """
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
     <html>
      <head>
       <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</title>
      </head>
      <body>
     <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</h1>
     <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
     <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 20M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">2.4K</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 58M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">  - </td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="nexus-4.zip">nexus-4.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">141M</td><td>&nbsp;</td></tr>
     <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 17K</td><td>&nbsp;</td></tr>
     <tr><th colspan="5"><hr></th></tr>
     </table>
     </body></html>
     """
     self.expect_result_packages_all = {
         'images': 'nexus-4.zip',
         'gaia': 'gaia.zip',
         'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'
     }
Пример #7
0
class testPathParser(unittest.TestCase):
    def setUp(self):
        self.path_parser = PathParser()
        # For test_parser_root()
        self.test_html_root = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
           <title>Index of /pvt/mozilla.org/b2gotoro/nightly</title>
         </head>
         <body>
         <h1>Index of /pvt/mozilla.org/b2gotoro/nightly</h1>
         <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
         <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-aurora-hamachi-eng/">mozilla-aurora-hamachi-eng/</a></td><td align="right">03-Apr-2014 00:44  </td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="mozilla-central-nexus-4-eng/">mozilla-central-nexus-4-eng/</a></td><td align="right">03-Apr-2014 00:56  </td><td align="right">  - </td><td>&nbsp;</td></tr>
         <tr><th colspan="5"><hr></th></tr>
         </table>
         </body>
        </html>
        """
        self.expect_result_root = {
            'nexus-4': {
                'central': {
                    'Engineer': {
                        'src': 'mozilla-central-nexus-4-eng',
                        'last_modify_time': '03-Apr-2014 00:56'
                    }
                }
            },
            'hamachi': {
                'aurora': {
                    'Engineer': {
                        'src': 'mozilla-aurora-hamachi-eng',
                        'last_modify_time': '03-Apr-2014 00:44'
                    }
                }
            }
        }
        # For test_parser_packages_gaia_gecko()
        self.test_html_packages_src_gaia_gecko = 'mozilla-central-hamachi-eng'
        self.test_html_packages_gaia_gecko = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
          <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</title>
         </head>
         <body>
        <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/latest</h1>
        <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
        <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-hamachi-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 21M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">5.9K</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 51M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:43  </td><td align="right"> 12K</td><td>&nbsp;</td></tr>
        <tr><th colspan="5"><hr></th></tr>
        </table>
        </body></html>
        """
        self.expect_result_packages_gaia_gecko = {
            'gaia': 'gaia.zip',
            'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'
        }
        # For test_parser_packages_all()
        self.test_html_packages_src_all = 'mozilla-central-nexus-4-eng'
        self.test_html_packages_all = """
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
        <html>
         <head>
          <title>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</title>
         </head>
         <body>
        <h1>Index of /pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/latest</h1>
        <table><tr><th><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr><tr><th colspan="5"><hr></th></tr>
        <tr><td valign="top"><img src="/icons/back.gif" alt="[DIR]"></td><td><a href="/pvt/mozilla.org/b2gotoro/nightly/mozilla-central-nexus-4-eng/">Parent Directory</a></td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip">b2g-31.0a1.en-US.android-arm.crashreporter-symbols.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 32M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="b2g-31.0a1.en-US.android-arm.tar.gz">b2g-31.0a1.en-US.android-arm.tar.gz</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 20M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="build.prop">build.prop</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">2.4K</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="gaia.zip">gaia.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 58M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="logs/">logs/</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">  - </td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/compressed.gif" alt="[   ]"></td><td><a href="nexus-4.zip">nexus-4.zip</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right">141M</td><td>&nbsp;</td></tr>
        <tr><td valign="top"><img src="/icons/text.gif" alt="[TXT]"></td><td><a href="sources.xml">sources.xml</a></td><td align="right">07-Apr-2014 00:40  </td><td align="right"> 17K</td><td>&nbsp;</td></tr>
        <tr><th colspan="5"><hr></th></tr>
        </table>
        </body></html>
        """
        self.expect_result_packages_all = {
            'images': 'nexus-4.zip',
            'gaia': 'gaia.zip',
            'gecko': 'b2g-31.0a1.en-US.android-arm.tar.gz'
        }

    def test_parser_root(self):
        '''
        Test parsing the HTML page which contains the builds list.
        '''
        result = self.path_parser._parse_device_version_and_time_from_list(
            self.path_parser._parse_build_and_time_from_html(
                self.test_html_root))
        self.assertEqual(result, self.expect_result_root)

    def test_parser_packages_gaia_gecko(self):
        '''
        Test parsing the gaia/gecko from Builds page.
        '''
        result = self.path_parser._parse_available_packages(
            self.test_html_packages_src_gaia_gecko,
            self.test_html_packages_gaia_gecko)
        self.assertEqual(result, self.expect_result_packages_gaia_gecko)

    def test_parser_packages_all(self):
        '''
        Test parsing the gaia/gecko/images from Builds page.
        '''
        result = self.path_parser._parse_available_packages(
            self.test_html_packages_src_all, self.test_html_packages_all)
        self.assertEqual(result, self.expect_result_packages_all)

    def test_verify_build_id(self):
        '''
        Test verifying the build id.
        '''
        self.assertTrue(self.path_parser._verify_build_id('20140408160201'))
        self.assertTrue(
            self.path_parser._verify_build_id('2014-04-08-16-02-01'))
        self.assertFalse(
            self.path_parser._verify_build_id('2014-04-08-16-02-01-0000'))
        self.assertFalse(
            self.path_parser._verify_build_id('This is not build id'))

    def test_get_path_of_build_id(self):
        '''
        Test the build id translation.
        '''
        self.assertEqual(
            '/2014/04/2014-04-08-16-02-01/',
            self.path_parser._get_path_of_build_id('2014-04-08-16-02-01'))
        self.assertEqual(
            '/2014/04/2014-04-13-16-02-02/',
            self.path_parser._get_path_of_build_id('2014-04-13-16-02-02'))