Package intelhex :: Module test
[hide private]
[frames] | no frames]

Source Code for Module intelhex.test

   1  #!/usr/bin/python 
   2   
   3  # Copyright (c) 2005-2009, Alexander Belchenko 
   4  # All rights reserved. 
   5  # 
   6  # Redistribution and use in source and binary forms, 
   7  # with or without modification, are permitted provided 
   8  # that the following conditions are met: 
   9  # 
  10  # * Redistributions of source code must retain 
  11  #   the above copyright notice, this list of conditions 
  12  #   and the following disclaimer. 
  13  # * Redistributions in binary form must reproduce 
  14  #   the above copyright notice, this list of conditions 
  15  #   and the following disclaimer in the documentation 
  16  #   and/or other materials provided with the distribution. 
  17  # * Neither the name of the author nor the names 
  18  #   of its contributors may be used to endorse 
  19  #   or promote products derived from this software 
  20  #   without specific prior written permission. 
  21  # 
  22  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
  23  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
  24  # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
  25  # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
  26  # IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
  27  # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
  28  # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  29  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  30  # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
  31  # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  32  # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  33  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
  34  # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  35   
  36  """Test suite for IntelHex class.""" 
  37   
  38  import array 
  39  from cStringIO import StringIO 
  40  import os 
  41  import sys 
  42  import tempfile 
  43  import unittest 
  44   
  45  import intelhex 
  46  from intelhex import IntelHex, \ 
  47                       IntelHexError, \ 
  48                       HexReaderError, \ 
  49                       AddressOverlapError, \ 
  50                       HexRecordError, \ 
  51                       RecordLengthError, \ 
  52                       RecordTypeError, \ 
  53                       RecordChecksumError, \ 
  54                       EOFRecordError, \ 
  55                       ExtendedSegmentAddressRecordError, \ 
  56                       ExtendedLinearAddressRecordError, \ 
  57                       StartSegmentAddressRecordError, \ 
  58                       StartLinearAddressRecordError, \ 
  59                       DuplicateStartAddressRecordError, \ 
  60                       InvalidStartAddressValueError, \ 
  61                       _EndOfFile, \ 
  62                       BadAccess16bit, \ 
  63                       hex2bin, \ 
  64                       Record 
  65   
  66   
  67  __docformat__ = 'restructuredtext' 
  68   
  69  ## 
  70  # Data for tests 
  71   
  72  hex8 = '''\ 
  73  :1004E300CFF0FBE2FDF220FF20F2E120E2FBE6F396 
  74  :1004F3000A00FDE0E1E2E3B4E4E5BAE6E7B3BFE80E 
  75  :10050300E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8E0 
  76  :10051300F9FCFEFF00C0C1C2C3A5C4C5AAC6C7B2C9 
  77  :10052300AFC8C9CACBCCCDCECFD0D1D2D3D4D5D6F8 
  78  :07053300D7D8D9DCDEDF00A0 
  79  :10053A0078227C007D007BFF7A0479F57E007F2398 
  80  :10054A0012042F78457C007D007BFF7A0579187E9E 
  81  :10055A00007F2212042F759850438920758DDDD2B1 
  82  :10056A008ED2996390017BFF7A0479E31200658049 
  83  :01057A00FE82 
  84  :030000000205A254 
  85  :0C05A200787FE4F6D8FD75817A02053AF6 
  86  :10035F00E709F608DFFA8046E709F208DFFA803E80 
  87  :10036F0088828C83E709F0A3DFFA8032E309F6086D 
  88  :10037F00DFFA8078E309F208DFFA807088828C83D5 
  89  :10038F00E309F0A3DFFA806489828A83E0A3F60889 
  90  :10039F00DFFA805889828A83E0A3F208DFFA804C63 
  91  :1003AF0080D280FA80C680D4806980F2803380103A 
  92  :1003BF0080A680EA809A80A880DA80E280CA8033A3 
  93  :1003CF0089828A83ECFAE493A3C8C582C8CCC5831B 
  94  :1003DF00CCF0A3C8C582C8CCC583CCDFE9DEE780EB 
  95  :1003EF000D89828A83E493A3F608DFF9ECFAA9F06A 
  96  :1003FF00EDFB2289828A83ECFAE0A3C8C582C8CCC0 
  97  :10040F00C583CCF0A3C8C582C8CCC583CCDFEADED8 
  98  :10041F00E880DB89828A83E493A3F208DFF980CC3A 
  99  :10042F0088F0EF60010E4E60C388F0ED2402B40433 
 100  :10043F000050B9F582EB2402B4040050AF232345DA 
 101  :06044F0082239003AF734D 
 102  :10000300E576246AF8E60576227867300702786A8F 
 103  :10001300E475F0011204AD0204552000EB7F2ED2EB 
 104  :10002300008018EF540F2490D43440D4FF30040BD5 
 105  :10003300EF24BFB41A0050032461FFE57760021573 
 106  :1000430077057AE57A7002057930070D7867E475EC 
 107  :10005300F0011204ADEF02049B02057B7403D20787 
 108  :100063008003E4C207F5768B678A688969E4F577CC 
 109  :10007300F579F57AE57760077F2012003E80F57504 
 110  :1000830078FFC201C200C202C203C205C206C2088F 
 111  :1000930012000CFF700D3007057F0012004FAF7A7E 
 112  :1000A300AE7922B4255FC2D5C20412000CFF24D05E 
 113  :1000B300B40A00501A75F00A787730D50508B6FFF0 
 114  :1000C3000106C6A426F620D5047002D20380D924E3 
 115  :1000D300CFB41A00EF5004C2E5D20402024FD2019A 
 116  :1000E30080C6D20080C0D20280BCD2D580BAD205ED 
 117  :1000F30080B47F2012003E2002077401B5770040D0 
 118  :10010300F1120003FF12003E020077D208D20680EC 
 119  :1001130095120003FB120003FA120003F94A4B7015 
 120  :100123000679207A037BFF20022EE577602A7E0082 
 121  :100133008E8275830012046E60060EEE657870F091 
 122  :10014300C2D5EBC0E0EAC0E0E9C0E0EE120296D00F 
 123  :10015300E0F9D0E0FAD0E0FB120455FF60AAEBC04F 
 124  :10016300E0EAC0E0E9C0E012003ED0E02401F9D0AB 
 125  :10017300E03400FAD0E0FBE5780460DCD578D98080 
 126  :10018300877BFF7A027992D202809C791080027970 
 127  :1001930008C206C2088008D2D5790A8004790AC247 
 128  :1001A300D5E578047002F578E4FAFDFEFF1200034A 
 129  :1001B300FC7B08200113120003FD7B1030000A12A0 
 130  :1001C3000003FE120003FF7B20EC3382D592D5504F 
 131  :1001D30013C3E43000069FFFE49EFEE42001039D69 
 132  :1001E300FDE49CFCE4CBF8C201EC700CCFCECDCC8B 
 133  :1001F300E824F8F870F38017C3EF33FFEE33FEED16 
 134  :1002030033FDEC33FCEB33FB994002FB0FD8E9EBF6 
 135  :10021300300105F8D0E0C448B201C0E00AEC4D4E0D 
 136  :100223004F78207B0070C2EAB5780040BCC0E01272 
 137  :100233000298D0F0D0E0200104C4C0E0C4B201C0F1 
 138  :10024300F0120027D0F0D5F0EB0200771204BD01C5 
 139  :100253001453018E5800E54C00E14201924F019A7C 
 140  :0F02630044019A4900FA4301A0550184460184E1 
 141  :100272004501844703405000E92D00ED2E01102B6B 
 142  :1002820000F123010E2003292A00A94800000108D9 
 143  :100292003F3F3F00790AA2D5200314300509B91067 
 144  :1002A200020404B9080104A2D52006025001042068 
 145  :1002B20002689202B577005034C0E07F2030031903 
 146  :1002C2007F30A20272067205500F1202EFC202C202 
 147  :1002D20006C205C2087F30800F300503E9C0E01274 
 148  :1002E200003E300503D0E0F9D0E0B577CC300517F9 
 149  :1002F2007F30B9100C12003E7F583004077F78809F 
 150  :1003020003B9080312003E3002057F2D02003E7F32 
 151  :10031200202008F87F2B2006F322920280CF286E3D 
 152  :10032200756C6C2900D2011200033001F8C2017809 
 153  :100332007730D50108F60200A92D50434958120022 
 154  :10034200032403B405004001E490033B9312002F01 
 155  :0D035200743A12002FD20375770402018E59 
 156  :10045500BB010689828A83E0225002E722BBFE02A5 
 157  :09046500E32289828A83E49322D8 
 158  :10046E00BB010CE58229F582E5833AF583E0225043 
 159  :10047E0006E92582F8E622BBFE06E92582F8E2228D 
 160  :0D048E00E58229F582E5833AF583E49322A7 
 161  :10049B00BB010689828A83F0225002F722BBFE0140 
 162  :0204AB00F3223A 
 163  :1004AD00FAE6FB0808E6F925F0F618E6CA3AF62250 
 164  :1004BD00D083D082F8E4937012740193700DA3A3CE 
 165  :1004CD0093F8740193F5828883E4737402936860E2 
 166  :0604DD00EFA3A3A380DFE2 
 167  :10057B00EFB40A07740D120586740A309811A89906 
 168  :10058B00B8130CC2983098FDA899C298B811F630E0 
 169  :07059B0099FDC299F59922B8 
 170  :00000001FF 
 171  ''' 
 172  bin8 = array.array('B',[2, 5, 162, 229, 118, 36, 106, 248, 230, 5, 118, 34, 
 173                          120, 103, 48, 7, 2, 120, 106, 228, 117, 240, 1, 18, 
 174                          4, 173, 2, 4, 85, 32, 0, 235, 127, 46, 210, 0, 128, 
 175                          24, 239, 84, 15, 36, 144, 212, 52, 64, 212, 255, 48, 
 176                          4, 11, 239, 36, 191, 180, 26, 0, 80, 3, 36, 97, 255, 
 177                          229, 119, 96, 2, 21, 119, 5, 122, 229, 122, 112, 2, 
 178                          5, 121, 48, 7, 13, 120, 103, 228, 117, 240, 1, 18, 
 179                          4, 173, 239, 2, 4, 155, 2, 5, 123, 116, 3, 210, 7, 
 180                          128, 3, 228, 194, 7, 245, 118, 139, 103, 138, 104, 
 181                          137, 105, 228, 245, 119, 245, 121, 245, 122, 229, 
 182                          119, 96, 7, 127, 32, 18, 0, 62, 128, 245, 117, 120, 
 183                          255, 194, 1, 194, 0, 194, 2, 194, 3, 194, 5, 194, 6, 
 184                          194, 8, 18, 0, 12, 255, 112, 13, 48, 7, 5, 127, 0, 
 185                          18, 0, 79, 175, 122, 174, 121, 34, 180, 37, 95, 194, 
 186                          213, 194, 4, 18, 0, 12, 255, 36, 208, 180, 10, 0, 80, 
 187                          26, 117, 240, 10, 120, 119, 48, 213, 5, 8, 182, 255, 
 188                          1, 6, 198, 164, 38, 246, 32, 213, 4, 112, 2, 210, 3, 
 189                          128, 217, 36, 207, 180, 26, 0, 239, 80, 4, 194, 229, 
 190                          210, 4, 2, 2, 79, 210, 1, 128, 198, 210, 0, 128, 192, 
 191                          210, 2, 128, 188, 210, 213, 128, 186, 210, 5, 128, 
 192                          180, 127, 32, 18, 0, 62, 32, 2, 7, 116, 1, 181, 119, 
 193                          0, 64, 241, 18, 0, 3, 255, 18, 0, 62, 2, 0, 119, 210, 
 194                          8, 210, 6, 128, 149, 18, 0, 3, 251, 18, 0, 3, 250, 
 195                          18, 0, 3, 249, 74, 75, 112, 6, 121, 32, 122, 3, 123, 
 196                          255, 32, 2, 46, 229, 119, 96, 42, 126, 0, 142, 130, 
 197                          117, 131, 0, 18, 4, 110, 96, 6, 14, 238, 101, 120, 
 198                          112, 240, 194, 213, 235, 192, 224, 234, 192, 224, 
 199                          233, 192, 224, 238, 18, 2, 150, 208, 224, 249, 208, 
 200                          224, 250, 208, 224, 251, 18, 4, 85, 255, 96, 170, 
 201                          235, 192, 224, 234, 192, 224, 233, 192, 224, 18, 0, 
 202                          62, 208, 224, 36, 1, 249, 208, 224, 52, 0, 250, 208, 
 203                          224, 251, 229, 120, 4, 96, 220, 213, 120, 217, 128, 
 204                          135, 123, 255, 122, 2, 121, 146, 210, 2, 128, 156, 
 205                          121, 16, 128, 2, 121, 8, 194, 6, 194, 8, 128, 8, 210, 
 206                          213, 121, 10, 128, 4, 121, 10, 194, 213, 229, 120, 4, 
 207                          112, 2, 245, 120, 228, 250, 253, 254, 255, 18, 0, 3, 
 208                          252, 123, 8, 32, 1, 19, 18, 0, 3, 253, 123, 16, 48, 
 209                          0, 10, 18, 0, 3, 254, 18, 0, 3, 255, 123, 32, 236, 
 210                          51, 130, 213, 146, 213, 80, 19, 195, 228, 48, 0, 6, 
 211                          159, 255, 228, 158, 254, 228, 32, 1, 3, 157, 253, 
 212                          228, 156, 252, 228, 203, 248, 194, 1, 236, 112, 12, 
 213                          207, 206, 205, 204, 232, 36, 248, 248, 112, 243, 128, 
 214                          23, 195, 239, 51, 255, 238, 51, 254, 237, 51, 253, 
 215                          236, 51, 252, 235, 51, 251, 153, 64, 2, 251, 15, 216, 
 216                          233, 235, 48, 1, 5, 248, 208, 224, 196, 72, 178, 1, 
 217                          192, 224, 10, 236, 77, 78, 79, 120, 32, 123, 0, 112, 
 218                          194, 234, 181, 120, 0, 64, 188, 192, 224, 18, 2, 152, 
 219                          208, 240, 208, 224, 32, 1, 4, 196, 192, 224, 196, 
 220                          178, 1, 192, 240, 18, 0, 39, 208, 240, 213, 240, 235, 
 221                          2, 0, 119, 18, 4, 189, 1, 20, 83, 1, 142, 88, 0, 229, 
 222                          76, 0, 225, 66, 1, 146, 79, 1, 154, 68, 1, 154, 73, 
 223                          0, 250, 67, 1, 160, 85, 1, 132, 70, 1, 132, 69, 1, 
 224                          132, 71, 3, 64, 80, 0, 233, 45, 0, 237, 46, 1, 16, 
 225                          43, 0, 241, 35, 1, 14, 32, 3, 41, 42, 0, 169, 72, 0, 
 226                          0, 1, 8, 63, 63, 63, 0, 121, 10, 162, 213, 32, 3, 20, 
 227                          48, 5, 9, 185, 16, 2, 4, 4, 185, 8, 1, 4, 162, 213, 
 228                          32, 6, 2, 80, 1, 4, 32, 2, 104, 146, 2, 181, 119, 0, 
 229                          80, 52, 192, 224, 127, 32, 48, 3, 25, 127, 48, 162, 
 230                          2, 114, 6, 114, 5, 80, 15, 18, 2, 239, 194, 2, 194, 
 231                          6, 194, 5, 194, 8, 127, 48, 128, 15, 48, 5, 3, 233, 
 232                          192, 224, 18, 0, 62, 48, 5, 3, 208, 224, 249, 208, 
 233                          224, 181, 119, 204, 48, 5, 23, 127, 48, 185, 16, 12, 
 234                          18, 0, 62, 127, 88, 48, 4, 7, 127, 120, 128, 3, 185, 
 235                          8, 3, 18, 0, 62, 48, 2, 5, 127, 45, 2, 0, 62, 127, 
 236                          32, 32, 8, 248, 127, 43, 32, 6, 243, 34, 146, 2, 128, 
 237                          207, 40, 110, 117, 108, 108, 41, 0, 210, 1, 18, 0, 3, 
 238                          48, 1, 248, 194, 1, 120, 119, 48, 213, 1, 8, 246, 2, 
 239                          0, 169, 45, 80, 67, 73, 88, 18, 0, 3, 36, 3, 180, 5, 
 240                          0, 64, 1, 228, 144, 3, 59, 147, 18, 0, 47, 116, 58, 
 241                          18, 0, 47, 210, 3, 117, 119, 4, 2, 1, 142, 231, 9, 
 242                          246, 8, 223, 250, 128, 70, 231, 9, 242, 8, 223, 250, 
 243                          128, 62, 136, 130, 140, 131, 231, 9, 240, 163, 223, 
 244                          250, 128, 50, 227, 9, 246, 8, 223, 250, 128, 120, 
 245                          227, 9, 242, 8, 223, 250, 128, 112, 136, 130, 140, 
 246                          131, 227, 9, 240, 163, 223, 250, 128, 100, 137, 
 247                          130, 138, 131, 224, 163, 246, 8, 223, 250, 128, 88, 
 248                          137, 130, 138, 131, 224, 163, 242, 8, 223, 250, 128, 
 249                          76, 128, 210, 128, 250, 128, 198, 128, 212, 128, 105, 
 250                          128, 242, 128, 51, 128, 16, 128, 166, 128, 234, 128, 
 251                          154, 128, 168, 128, 218, 128, 226, 128, 202, 128, 51, 
 252                          137, 130, 138, 131, 236, 250, 228, 147, 163, 200, 
 253                          197, 130, 200, 204, 197, 131, 204, 240, 163, 200, 
 254                          197, 130, 200, 204, 197, 131, 204, 223, 233, 222, 
 255                          231, 128, 13, 137, 130, 138, 131, 228, 147, 163, 246, 
 256                          8, 223, 249, 236, 250, 169, 240, 237, 251, 34, 137, 
 257                          130, 138, 131, 236, 250, 224, 163, 200, 197, 130, 
 258                          200, 204, 197, 131, 204, 240, 163, 200, 197, 130, 
 259                          200, 204, 197, 131, 204, 223, 234, 222, 232, 128, 
 260                          219, 137, 130, 138, 131, 228, 147, 163, 242, 8, 
 261                          223, 249, 128, 204, 136, 240, 239, 96, 1, 14, 78, 
 262                          96, 195, 136, 240, 237, 36, 2, 180, 4, 0, 80, 185, 
 263                          245, 130, 235, 36, 2, 180, 4, 0, 80, 175, 35, 35, 
 264                          69, 130, 35, 144, 3, 175, 115, 187, 1, 6, 137, 130, 
 265                          138, 131, 224, 34, 80, 2, 231, 34, 187, 254, 2, 227, 
 266                          34, 137, 130, 138, 131, 228, 147, 34, 187, 1, 12, 
 267                          229, 130, 41, 245, 130, 229, 131, 58, 245, 131, 224, 
 268                          34, 80, 6, 233, 37, 130, 248, 230, 34, 187, 254, 6, 
 269                          233, 37, 130, 248, 226, 34, 229, 130, 41, 245, 130, 
 270                          229, 131, 58, 245, 131, 228, 147, 34, 187, 1, 6, 
 271                          137, 130, 138, 131, 240, 34, 80, 2, 247, 34, 187, 
 272                          254, 1, 243, 34, 250, 230, 251, 8, 8, 230, 249, 37, 
 273                          240, 246, 24, 230, 202, 58, 246, 34, 208, 131, 208, 
 274                          130, 248, 228, 147, 112, 18, 116, 1, 147, 112, 13, 
 275                          163, 163, 147, 248, 116, 1, 147, 245, 130, 136, 
 276                          131, 228, 115, 116, 2, 147, 104, 96, 239, 163, 163, 
 277                          163, 128, 223, 207, 240, 251, 226, 253, 242, 32, 
 278                          255, 32, 242, 225, 32, 226, 251, 230, 243, 10, 0, 
 279                          253, 224, 225, 226, 227, 180, 228, 229, 186, 230, 
 280                          231, 179, 191, 232, 233, 234, 235, 236, 237, 238, 
 281                          239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 
 282                          249, 252, 254, 255, 0, 192, 193, 194, 195, 165, 196, 
 283                          197, 170, 198, 199, 178, 175, 200, 201, 202, 203, 
 284                          204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 
 285                          214, 215, 216, 217, 220, 222, 223, 0, 120, 34, 124, 
 286                          0, 125, 0, 123, 255, 122, 4, 121, 245, 126, 0, 127, 
 287                          35, 18, 4, 47, 120, 69, 124, 0, 125, 0, 123, 255, 
 288                          122, 5, 121, 24, 126, 0, 127, 34, 18, 4, 47, 117, 
 289                          152, 80, 67, 137, 32, 117, 141, 221, 210, 142, 210, 
 290                          153, 99, 144, 1, 123, 255, 122, 4, 121, 227, 18, 0, 
 291                          101, 128, 254, 239, 180, 10, 7, 116, 13, 18, 5, 134, 
 292                          116, 10, 48, 152, 17, 168, 153, 184, 19, 12, 194, 
 293                          152, 48, 152, 253, 168, 153, 194, 152, 184, 17, 
 294                          246, 48, 153, 253, 194, 153, 245, 153, 34, 120, 127, 
 295                          228, 246, 216, 253, 117, 129, 122, 2, 5, 58]) 
 296   
 297   
 298  hex16 = """:020000040000FA 
 299  :10000000000083120313072055301820042883169C 
 300  :10001000031340309900181598168312031318160D 
 301  :1000200098170800831203138C1E14281A0808005E 
 302  :0C003000831203130C1E1A28990008000C 
 303  :00000001FF 
 304  """ 
 305  bin16 = array.array('H', [0x0000, 0x1283, 0x1303, 0x2007, 
 306                            0x3055, 0x2018, 0x2804, 0x1683, 
 307                            0x1303, 0x3040, 0x0099, 0x1518, 
 308                            0x1698, 0x1283, 0x1303, 0x1618, 
 309                            0x1798, 0x0008, 0x1283, 0x1303, 
 310                            0x1E8C, 0x2814, 0x081A, 0x0008, 
 311                            0x1283, 0x1303, 0x1E0C, 0x281A, 
 312                            0x0099, 0x0008, 0x3FFF, 0x3FFF]) 
 313   
 314   
 315  hex64k = """:020000040000FA 
 316  :0100000001FE 
 317  :020000040001F9 
 318  :0100000002FD 
 319  :00000001FF 
 320  """ 
 321  data64k = {0: 1, 0x10000: 2} 
 322   
 323   
 324  hex_rectype3 = """:0400000312345678E5 
 325  :0100000001FE 
 326  :00000001FF 
 327  """ 
 328  data_rectype3 = {0: 1} 
 329  start_addr_rectype3 = {'CS': 0x1234, 'IP': 0x5678} 
 330   
 331   
 332  hex_rectype5 = """:0400000512345678E3 
 333  :0100000002FD 
 334  :00000001FF 
 335  """ 
 336  data_rectype5 = {0: 2} 
 337  start_addr_rectype5 = {'EIP': 0x12345678} 
 338   
 339  hex_empty_file = ':00000001FF\n' 
 340   
 341  hex_simple = """\ 
 342  :10000000000083120313072055301820042883169C 
 343  :10001000031340309900181598168312031318160D 
 344  :1000200098170800831203138C1E14281A0808005E 
 345  :0C003000831203130C1E1A28990008000C 
 346  :00000001FF 
 347  """ 
 348   
 349  hex_bug_lp_341051 = """\ 
 350  :020FEC00E4E738 
 351  :040FF00022E122E1F7 
 352  :00000001FF 
 353  """ 
 354   
 355   
 356  ## 
 357  # Test cases 
 358   
359 -class TestIntelHexBase(unittest.TestCase):
360 """Base class for all tests. 361 Provide additional functionality for testing. 362 """ 363
364 - def assertRaisesMsg(self, excClass, msg, callableObj, *args, **kwargs):
365 """Just like unittest.TestCase.assertRaises, 366 but checks that the message is right too. 367 368 Borrowed from Ned Batchelder Blog. 369 See: http://www.nedbatchelder.com/blog/200609.html#e20060905T064418 370 371 Typical usage:: 372 373 self.assertRaisesMsg(MyException, "Exception message", 374 my_function, (arg1, arg2)) 375 """ 376 try: 377 callableObj(*args, **kwargs) 378 except excClass, exc: 379 excMsg = str(exc) 380 if not msg: 381 # No message provided: any message is fine. 382 return 383 elif excMsg == msg: 384 # Message provided, and we got the right message: it passes. 385 return 386 else: 387 # Message provided, and it didn't match: fail! 388 raise self.failureException( 389 "Right exception, wrong message: got '%s' expected '%s'" % 390 (excMsg, msg) 391 ) 392 else: 393 if hasattr(excClass, '__name__'): 394 excName = excClass.__name__ 395 else: 396 excName = str(excClass) 397 raise self.failureException( 398 "Expected to raise %s, didn't get an exception at all" % 399 excName 400 )
401
402 - def assertEqualWrittenData(self, a, b):
403 return self.assertEquals(a, b, """Written data is incorrect 404 Should be: 405 %s 406 407 Written: 408 %s 409 """ % (a, b))
410 #/class TestIntelHexBase 411 412
413 -class TestIntelHex(TestIntelHexBase):
414
415 - def setUp(self):
416 self.f = StringIO(hex8)
417
418 - def tearDown(self):
419 self.f.close() 420 del self.f
421
422 - def test_init_from_file(self):
423 ih = IntelHex(self.f) 424 for addr in xrange(len(bin8)): 425 expected = bin8[addr] 426 actual = ih[addr] 427 self.assertEqual(expected, actual, 428 "Data different at address " 429 "%x (%x != %x)" % (addr, expected, actual))
430
431 - def test_hex_fromfile(self):
432 ih = IntelHex() 433 ih.fromfile(self.f, format='hex') 434 for addr in xrange(len(bin8)): 435 expected = bin8[addr] 436 actual = ih[addr] 437 self.assertEqual(expected, actual, 438 "Data different at address " 439 "%x (%x != %x)" % (addr, expected, actual))
440
441 - def test_unicode_filename(self):
442 handle, fname = tempfile.mkstemp(u'') 443 os.close(handle) 444 try: 445 self.assertTrue(isinstance(fname, unicode)) 446 f = file(fname, 'w') 447 try: 448 f.write(hex8) 449 finally: 450 f.close() 451 ih = IntelHex(fname) 452 self.assertEqual(0, ih.minaddr()) 453 self.assertEqual(len(bin8)-1, ih.maxaddr()) 454 finally: 455 os.remove(fname)
456
457 - def test_tobinarray_empty(self):
458 ih = IntelHex() 459 self.assertEqual(array.array('B', []), ih.tobinarray(pad=0xFF)) 460 self.assertEqual(array.array('B', []), ih.tobinarray(start=0,pad=0xFF)) 461 self.assertEqual(array.array('B', []), ih.tobinarray(end=2,pad=0xFF)) 462 self.assertEqual(array.array('B', [255,255,255]), ih.tobinarray(0,2,pad=0xFF))
463
464 - def test_tobinarray_with_size(self):
465 ih = IntelHex(self.f) 466 self.assertEqual(array.array('B', [2, 5, 162, 229, 118, 36, 106, 248]), 467 ih.tobinarray(size=8)) # from addr 0 468 self.assertEqual(array.array('B', [120, 103, 48, 7, 2, 120, 106, 228]), 469 ih.tobinarray(start=12, size=8)) 470 self.assertEqual(array.array('B', [2, 5, 162, 229, 118, 36, 106, 248]), 471 ih.tobinarray(end=7, size=8)) # addr: 0..7, 8 bytes 472 self.assertEqual(array.array('B', [120, 103, 48, 7, 2, 120, 106, 228]), 473 ih.tobinarray(end=19, size=8)) # addr: 12..19, 8 bytes 474 self.assertRaises(ValueError, ih.tobinarray, start=0, end=7, size=8) 475 self.assertRaises(ValueError, ih.tobinarray, end=3, size=8) 476 self.assertRaises(ValueError, ih.tobinarray, size=0) 477 self.assertRaises(ValueError, ih.tobinarray, size=-1)
478
479 - def test_tobinstr(self):
480 ih = IntelHex(self.f) 481 s1 = ih.tobinstr() 482 s2 = bin8.tostring() 483 self.assertEqual(s2, s1, "data not equal\n%s\n\n%s" % (s1, s2))
484
485 - def test_tobinfile(self):
486 ih = IntelHex(self.f) 487 sio = StringIO() 488 ih.tobinfile(sio) 489 s1 = sio.getvalue() 490 sio.close() 491 s2 = bin8.tostring() 492 self.assertEqual(s2, s1, "data not equal\n%s\n\n%s" % (s1, s2)) 493 # new API: .tofile universal method 494 sio = StringIO() 495 ih.tofile(sio, format='bin') 496 s1 = sio.getvalue() 497 sio.close() 498 s2 = bin8.tostring() 499 self.assertEqual(s2, s1, "data not equal\n%s\n\n%s" % (s1, s2))
500
501 - def test_write_empty_hexfile(self):
502 ih = intelhex.IntelHex() 503 sio = StringIO() 504 ih.write_hex_file(sio) 505 s = sio.getvalue() 506 sio.close() 507 self.assertEqualWrittenData(hex_empty_file, s)
508
509 - def test_write_hexfile(self):
510 ih = intelhex.IntelHex(StringIO(hex_simple)) 511 sio = StringIO() 512 ih.write_hex_file(sio) 513 s = sio.getvalue() 514 sio.close() 515 self.assertEqualWrittenData(hex_simple, s) 516 # new API: .tofile universal method 517 sio = StringIO() 518 ih.tofile(sio, format='hex') 519 s = sio.getvalue() 520 sio.close() 521 self.assertEqualWrittenData(hex_simple, s)
522
523 - def test_write_hex_bug_341051(self):
524 ih = intelhex.IntelHex(StringIO(hex_bug_lp_341051)) 525 sio = StringIO() 526 ih.tofile(sio, format='hex') 527 s = sio.getvalue() 528 sio.close() 529 self.assertEqualWrittenData(hex_bug_lp_341051, s)
530
532 ih = IntelHex({0x20000: 0x01}) 533 sio = StringIO() 534 ih.write_hex_file(sio) 535 s = sio.getvalue() 536 sio.close() 537 # should be 538 r = [Record.extended_linear_address(2), 539 Record.data(0x0000, [0x01]), 540 Record.eof()] 541 h = '\n'.join(r) + '\n' 542 # compare 543 self.assertEqual(h, s)
544
545 - def test_tofile_wrong_format(self):
546 ih = IntelHex() 547 sio = StringIO() 548 self.assertRaises(ValueError, ih.tofile, sio, {'format': 'bad'})
549
550 - def test_todict(self):
551 ih = IntelHex() 552 self.assertEquals({}, ih.todict()) 553 ih = IntelHex(StringIO(hex64k)) 554 self.assertEquals(data64k, ih.todict()) 555 ih = IntelHex() 556 ih[1] = 2 557 ih.start_addr = {'EIP': 1234} 558 self.assertEquals({1: 2, 'start_addr': {'EIP': 1234}}, ih.todict())
559
560 - def test_fromdict(self):
561 ih = IntelHex() 562 ih.fromdict({1:2, 3:4}) 563 self.assertEquals({1:2, 3:4}, ih.todict()) 564 ih.fromdict({1:5, 6:7}) 565 self.assertEquals({1:5, 3:4, 6:7}, ih.todict()) 566 ih = IntelHex() 567 ih.fromdict({1: 2, 'start_addr': {'EIP': 1234}}) 568 self.assertEquals({1: 2, 'start_addr': {'EIP': 1234}}, ih.todict()) 569 # bad dict 570 self.assertRaises(ValueError, ih.fromdict, {'EIP': 1234}) 571 self.assertRaises(ValueError, ih.fromdict, {-1: 1234})
572
573 - def test_init_from_obj(self):
574 ih = IntelHex({1:2, 3:4}) 575 self.assertEquals({1:2, 3:4}, ih.todict()) 576 ih.start_addr = {'EIP': 1234} 577 ih2 = IntelHex(ih) 578 ih[1] = 5 579 ih.start_addr = {'EIP': 5678} 580 self.assertEquals({1:2, 3:4, 'start_addr': {'EIP': 1234}}, ih2.todict()) 581 self.assertNotEqual(id(ih), id(ih2))
582
583 - def test_dict_interface(self):
584 ih = IntelHex() 585 self.assertEquals(0xFF, ih[0]) # padding byte substitution 586 ih[0] = 1 587 self.assertEquals(1, ih[0]) 588 del ih[0] 589 self.assertEquals({}, ih.todict()) # padding byte substitution
590
591 - def test_len(self):
592 ih = IntelHex() 593 self.assertEquals(0, len(ih)) 594 ih[2] = 1 595 self.assertEquals(1, len(ih)) 596 ih[1000] = 2 597 self.assertEquals(2, len(ih))
598
599 - def test__getitem__(self):
600 ih = IntelHex() 601 # simple cases 602 self.assertEquals(0xFF, ih[0]) 603 ih[0] = 1 604 self.assertEquals(1, ih[0]) 605 # big address 606 self.assertEquals(0xFF, ih[2**32-1]) 607 # wrong addr type/value for indexing operations 608 def getitem(index): 609 return ih[index]
610 self.assertRaisesMsg(TypeError, 611 'Address should be >= 0.', 612 getitem, -1) 613 self.assertRaisesMsg(TypeError, 614 "Address has unsupported type: <type 'str'>", 615 getitem, 'foo') 616 # new object with some data 617 ih = IntelHex() 618 ih[0] = 1 619 ih[1] = 2 620 ih[2] = 3 621 ih[10] = 4 622 # full copy via slicing 623 ih2 = ih[:] 624 self.assertTrue(isinstance(ih2, IntelHex)) 625 self.assertEquals({0:1, 1:2, 2:3, 10:4}, ih2.todict()) 626 # other slice operations 627 self.assertEquals({}, ih[3:8].todict()) 628 self.assertEquals({0:1, 1:2}, ih[0:2].todict()) 629 self.assertEquals({0:1, 1:2}, ih[:2].todict()) 630 self.assertEquals({2:3, 10:4}, ih[2:].todict()) 631 self.assertEquals({0:1, 2:3, 10:4}, ih[::2].todict()) 632 self.assertEquals({10:4}, ih[3:11].todict())
633
634 - def test__setitem__(self):
635 ih = IntelHex() 636 # simple indexing operation 637 ih[0] = 1 638 self.assertEquals({0:1}, ih.todict()) 639 # errors 640 def setitem(a,b): 641 ih[a] = b
642 self.assertRaisesMsg(TypeError, 643 'Address should be >= 0.', 644 setitem, -1, 0) 645 self.assertRaisesMsg(TypeError, 646 "Address has unsupported type: <type 'str'>", 647 setitem, 'foo', 0) 648 # slice operations 649 ih[0:4] = range(4) 650 self.assertEquals({0:0, 1:1, 2:2, 3:3}, ih.todict()) 651 ih[0:] = range(5,9) 652 self.assertEquals({0:5, 1:6, 2:7, 3:8}, ih.todict()) 653 ih[:4] = range(9,13) 654 self.assertEquals({0:9, 1:10, 2:11, 3:12}, ih.todict()) 655 # with step 656 ih = IntelHex() 657 ih[0:8:2] = range(4) 658 self.assertEquals({0:0, 2:1, 4:2, 6:3}, ih.todict()) 659 # errors in slice operations 660 # ih[1:2] = 'a' 661 self.assertRaisesMsg(ValueError, 662 'Slice operation expects sequence of bytes', 663 setitem, slice(1,2,None), 'a') 664 # ih[0:1] = [1,2,3] 665 self.assertRaisesMsg(ValueError, 666 'Length of bytes sequence does not match address range', 667 setitem, slice(0,1,None), [1,2,3]) 668 # ih[:] = [1,2,3] 669 self.assertRaisesMsg(TypeError, 670 'Unsupported address range', 671 setitem, slice(None,None,None), [1,2,3]) 672 # ih[:2] = [1,2,3] 673 self.assertRaisesMsg(TypeError, 674 'start address cannot be negative', 675 setitem, slice(None,2,None), [1,2,3]) 676 # ih[0:-3:-1] = [1,2,3] 677 self.assertRaisesMsg(TypeError, 678 'stop address cannot be negative', 679 setitem, slice(0,-3,-1), [1,2,3]) 680
681 - def test__delitem__(self):
682 ih = IntelHex() 683 ih[0] = 1 684 del ih[0] 685 self.assertEquals({}, ih.todict()) 686 # errors 687 def delitem(addr): 688 del ih[addr]
689 self.assertRaises(KeyError, delitem, 1) 690 self.assertRaisesMsg(TypeError, 691 'Address should be >= 0.', 692 delitem, -1) 693 self.assertRaisesMsg(TypeError, 694 "Address has unsupported type: <type 'str'>", 695 delitem, 'foo') 696 # deleting slice 697 del ih[0:1] # no error here because of slicing 698 # 699 def ihex(size=8): 700 ih = IntelHex() 701 for i in xrange(size): 702 ih[i] = i 703 return ih 704 ih = ihex(8) 705 del ih[:] # delete all data 706 self.assertEquals({}, ih.todict()) 707 ih = ihex(8) 708 del ih[2:6] 709 self.assertEquals({0:0, 1:1, 6:6, 7:7}, ih.todict()) 710 ih = ihex(8) 711 del ih[::2] 712 self.assertEquals({1:1, 3:3, 5:5, 7:7}, ih.todict()) 713
714 - def test_addresses(self):
715 # empty object 716 ih = IntelHex() 717 self.assertEquals([], ih.addresses()) 718 self.assertEquals(None, ih.minaddr()) 719 self.assertEquals(None, ih.maxaddr()) 720 # normal object 721 ih = IntelHex({1:2, 7:8, 10:0}) 722 self.assertEquals([1,7,10], ih.addresses()) 723 self.assertEquals(1, ih.minaddr()) 724 self.assertEquals(10, ih.maxaddr())
725 726
727 -class TestIntelHexLoadBin(TestIntelHexBase):
728
729 - def setUp(self):
730 self.data = '0123456789' 731 self.f = StringIO(self.data)
732
733 - def tearDown(self):
734 self.f.close()
735
736 - def test_loadbin(self):
737 ih = IntelHex() 738 ih.loadbin(self.f) 739 self.assertEqual(0, ih.minaddr()) 740 self.assertEqual(9, ih.maxaddr()) 741 self.assertEqual(self.data, ih.tobinstr())
742
743 - def test_bin_fromfile(self):
744 ih = IntelHex() 745 ih.fromfile(self.f, format='bin') 746 self.assertEqual(0, ih.minaddr()) 747 self.assertEqual(9, ih.maxaddr()) 748 self.assertEqual(self.data, ih.tobinstr())
749
750 - def test_loadbin_w_offset(self):
751 ih = IntelHex() 752 ih.loadbin(self.f, offset=100) 753 self.assertEqual(100, ih.minaddr()) 754 self.assertEqual(109, ih.maxaddr()) 755 self.assertEqual(self.data, ih.tobinstr())
756
757 - def test_loadfile_format_bin(self):
758 ih = IntelHex() 759 ih.loadfile(self.f, format='bin') 760 self.assertEqual(0, ih.minaddr()) 761 self.assertEqual(9, ih.maxaddr()) 762 self.assertEqual(self.data, ih.tobinstr())
763 764
765 -class TestIntelHexStartingAddressRecords(TestIntelHexBase):
766
767 - def _test_read(self, hexstr, data, start_addr):
768 sio = StringIO(hexstr) 769 ih = IntelHex(sio) 770 sio.close() 771 # test data 772 self.assertEqual(data, ih._buf, 773 "Internal buffer: %r != %r" % 774 (data, ih._buf)) 775 self.assertEqual(start_addr, ih.start_addr, 776 "Start address: %r != %r" % 777 (start_addr, ih.start_addr))
778
779 - def test_read_rectype3(self):
781
782 - def test_read_rectype5(self):
784
785 - def _test_write(self, hexstr, data, start_addr, write_start_addr=True):
786 # prepare 787 ih = IntelHex(None) 788 ih._buf = data 789 ih.start_addr = start_addr 790 # write 791 sio = StringIO() 792 ih.write_hex_file(sio, write_start_addr) 793 s = sio.getvalue() 794 sio.close() 795 # check 796 self.assertEqualWrittenData(hexstr, s)
797
798 - def _test_dont_write(self, hexstr, data, start_addr):
799 expected = ''.join(hexstr.splitlines(True)[1:]) 800 self._test_write(expected, data, start_addr, False)
801
802 - def test_write_rectype3(self):
804
805 - def test_dont_write_rectype3(self):
807
808 - def test_write_rectype5(self):
810
811 - def test_dont_write_rectype5(self):
813
815 ih = IntelHex() 816 ih.start_addr = {'foo': 1} 817 sio = StringIO() 818 self.assertRaises(InvalidStartAddressValueError, ih.write_hex_file, sio)
819 820
821 -class TestIntelHex_big_files(TestIntelHexBase):
822 """Test that data bigger than 64K read/write correctly""" 823
824 - def setUp(self):
825 self.f = StringIO(hex64k)
826
827 - def tearDown(self):
828 self.f.close() 829 del self.f
830
831 - def test_readfile(self):
832 ih = intelhex.IntelHex(self.f) 833 for addr, byte in data64k.items(): 834 readed = ih[addr] 835 self.assertEquals(byte, readed, 836 "data not equal at addr %X " 837 "(%X != %X)" % (addr, byte, readed))
838
839 - def test_write_hex_file(self):
840 ih = intelhex.IntelHex(self.f) 841 sio = StringIO() 842 ih.write_hex_file(sio) 843 s = sio.getvalue() 844 sio.close() 845 self.assertEqualWrittenData(hex64k, s)
846 847
848 -class TestIntelHexGetPutString(TestIntelHexBase):
849
850 - def setUp(self):
851 self.ih = IntelHex() 852 for i in xrange(10): 853 self.ih[i] = i
854
855 - def test_gets(self):
856 self.assertEquals('\x00\x01\x02\x03\x04\x05\x06\x07', self.ih.gets(0, 8)) 857 self.assertEquals('\x07\x08\x09', self.ih.gets(7, 3)) 858 self.assertRaisesMsg(intelhex.NotEnoughDataError, 859 'Bad access at 0x1: ' 860 'not enough data to read 10 contiguous bytes', 861 self.ih.gets, 1, 10)
862
863 - def test_puts(self):
864 self.ih.puts(0x03, 'hello') 865 self.assertEquals('\x00\x01\x02hello\x08\x09', self.ih.gets(0, 10))
866
867 - def test_getsz(self):
868 self.assertEquals('', self.ih.getsz(0)) 869 self.assertRaisesMsg(intelhex.NotEnoughDataError, 870 'Bad access at 0x1: ' 871 'not enough data to read zero-terminated string', 872 self.ih.getsz, 1) 873 self.ih[4] = 0 874 self.assertEquals('\x01\x02\x03', self.ih.getsz(1))
875
876 - def test_putsz(self):
877 self.ih.putsz(0x03, 'hello') 878 self.assertEquals('\x00\x01\x02hello\x00\x09', self.ih.gets(0, 10))
879 880
881 -class TestIntelHexDump(TestIntelHexBase):
882
883 - def test_empty(self):
884 ih = IntelHex() 885 sio = StringIO() 886 ih.dump(sio) 887 self.assertEquals('', sio.getvalue())
888
889 - def test_simple(self):
890 ih = IntelHex() 891 ih[0] = 0x12 892 ih[1] = 0x34 893 sio = StringIO() 894 ih.dump(sio) 895 self.assertEquals( 896 '0000 12 34 -- -- -- -- -- -- -- -- -- -- -- -- -- -- |.4 |\n', 897 sio.getvalue()) 898 ih[16] = 0x56 899 ih[30] = 0x98 900 sio = StringIO() 901 ih.dump(sio) 902 self.assertEquals( 903 '0000 12 34 -- -- -- -- -- -- -- -- -- -- -- -- -- -- |.4 |\n' 904 '0010 56 -- -- -- -- -- -- -- -- -- -- -- -- -- 98 -- |V . |\n', 905 sio.getvalue())
906
907 - def test_minaddr_not_zero(self):
908 ih = IntelHex() 909 ih[16] = 0x56 910 ih[30] = 0x98 911 sio = StringIO() 912 ih.dump(sio) 913 self.assertEquals( 914 '0010 56 -- -- -- -- -- -- -- -- -- -- -- -- -- 98 -- |V . |\n', 915 sio.getvalue())
916
917 - def test_start_addr(self):
918 ih = IntelHex() 919 ih[0] = 0x12 920 ih[1] = 0x34 921 ih.start_addr = {'CS': 0x1234, 'IP': 0x5678} 922 sio = StringIO() 923 ih.dump(sio) 924 self.assertEquals( 925 'CS = 0x1234, IP = 0x5678\n' 926 '0000 12 34 -- -- -- -- -- -- -- -- -- -- -- -- -- -- |.4 |\n', 927 sio.getvalue()) 928 ih.start_addr = {'EIP': 0x12345678} 929 sio = StringIO() 930 ih.dump(sio) 931 self.assertEquals( 932 'EIP = 0x12345678\n' 933 '0000 12 34 -- -- -- -- -- -- -- -- -- -- -- -- -- -- |.4 |\n', 934 sio.getvalue())
935 936
937 -class TestIntelHexMerge(TestIntelHexBase):
938
939 - def test_merge_empty(self):
940 ih1 = IntelHex() 941 ih2 = IntelHex() 942 ih1.merge(ih2) 943 self.assertEquals({}, ih1.todict())
944
945 - def test_merge_simple(self):
946 ih1 = IntelHex({0:1, 1:2, 2:3}) 947 ih2 = IntelHex({3:4, 4:5, 5:6}) 948 ih1.merge(ih2) 949 self.assertEquals({0:1, 1:2, 2:3, 3:4, 4:5, 5:6}, ih1.todict())
950
951 - def test_merge_wrong_args(self):
952 ih1 = IntelHex() 953 self.assertRaisesMsg(TypeError, 'other should be IntelHex object', 954 ih1.merge, {0:1}) 955 self.assertRaisesMsg(ValueError, "Can't merge itself", 956 ih1.merge, ih1) 957 ih2 = IntelHex() 958 self.assertRaisesMsg(ValueError, "overlap argument should be either " 959 "'error', 'ignore' or 'replace'", 960 ih1.merge, ih2, overlap='spam')
961
962 - def test_merge_overlap(self):
963 # error 964 ih1 = IntelHex({0:1}) 965 ih2 = IntelHex({0:2}) 966 self.assertRaisesMsg(intelhex.AddressOverlapError, 967 'Data overlapped at address 0x0', 968 ih1.merge, ih2, overlap='error') 969 # ignore 970 ih1 = IntelHex({0:1}) 971 ih2 = IntelHex({0:2}) 972 ih1.merge(ih2, overlap='ignore') 973 self.assertEquals({0:1}, ih1.todict()) 974 # replace 975 ih1 = IntelHex({0:1}) 976 ih2 = IntelHex({0:2}) 977 ih1.merge(ih2, overlap='replace') 978 self.assertEquals({0:2}, ih1.todict())
979
980 - def test_merge_start_addr(self):
981 # this, None 982 ih1 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 983 ih2 = IntelHex() 984 ih1.merge(ih2) 985 self.assertEquals({'start_addr': {'EIP': 0x12345678}}, ih1.todict()) 986 # None, other 987 ih1 = IntelHex() 988 ih2 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 989 ih1.merge(ih2) 990 self.assertEquals({'start_addr': {'EIP': 0x12345678}}, ih1.todict()) 991 # this == other: no conflict 992 ih1 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 993 ih2 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 994 ih1.merge(ih2) 995 self.assertEquals({'start_addr': {'EIP': 0x12345678}}, ih1.todict()) 996 # this != other: conflict 997 ## overlap=error 998 ih1 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 999 ih2 = IntelHex({'start_addr': {'EIP': 0x87654321}}) 1000 self.assertRaisesMsg(AddressOverlapError, 1001 'Starting addresses are different', 1002 ih1.merge, ih2, overlap='error') 1003 ## overlap=ignore 1004 ih1 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 1005 ih2 = IntelHex({'start_addr': {'EIP': 0x87654321}}) 1006 ih1.merge(ih2, overlap='ignore') 1007 self.assertEquals({'start_addr': {'EIP': 0x12345678}}, ih1.todict()) 1008 ## overlap=replace 1009 ih1 = IntelHex({'start_addr': {'EIP': 0x12345678}}) 1010 ih2 = IntelHex({'start_addr': {'EIP': 0x87654321}}) 1011 ih1.merge(ih2, overlap='replace') 1012 self.assertEquals({'start_addr': {'EIP': 0x87654321}}, ih1.todict())
1013 1014
1015 -class TestIntelHex16bit(TestIntelHexBase):
1016
1017 - def setUp(self):
1018 self.f = StringIO(hex16)
1019
1020 - def tearDown(self):
1021 self.f.close() 1022 del self.f
1023
1024 - def test_init_from_file(self):
1025 ih = intelhex.IntelHex16bit(self.f)
1026
1027 - def test_init_from_ih(self):
1028 ih = intelhex.IntelHex(self.f) 1029 ih16 = intelhex.IntelHex16bit(ih)
1030
1031 - def test_minaddr(self):
1032 ih = intelhex.IntelHex16bit(self.f) 1033 addr = ih.minaddr() 1034 self.assertEqual(0, addr, 1035 'Error in detection of minaddr (0 != 0x%x)' % addr)
1036
1037 - def test_maxaddr(self):
1038 ih = intelhex.IntelHex16bit(self.f) 1039 addr = ih.maxaddr() 1040 self.assertEqual(0x001D, addr, 1041 'Error in detection of maxaddr ' 1042 '(0x001D != 0x%x)' % addr)
1043
1044 - def test_getitem(self):
1045 ih = intelhex.IntelHex16bit(self.f) 1046 ih.padding = 0x3FFF 1047 for addr, word in enumerate(bin16): 1048 self.assertEqual(word, ih[addr], 1049 'Data mismatch at address ' 1050 '0x%x (0x%x != 0x%x)' % (addr, word, ih[addr]))
1051
1052 - def test_not_enough_data(self):
1053 ih = intelhex.IntelHex() 1054 ih[0] = 1 1055 ih16 = intelhex.IntelHex16bit(ih) 1056 self.assertRaisesMsg(BadAccess16bit, 1057 'Bad access at 0x0: ' 1058 'not enough data to read 16 bit value', 1059 lambda x: ih16[x], 1060 0)
1061
1062 - def test_write_hex_file(self):
1063 ih = intelhex.IntelHex16bit(self.f) 1064 sio = StringIO() 1065 ih.write_hex_file(sio) 1066 s = sio.getvalue() 1067 sio.close() 1068 1069 fin = StringIO(s) 1070 ih2 = intelhex.IntelHex16bit(fin) 1071 1072 self.assertEqual(ih.tobinstr(), ih2.tobinstr(), 1073 "Written hex file does not equal with original")
1074
1075 - def test_setitem(self):
1076 ih = intelhex.IntelHex16bit(self.f) 1077 1078 old = ih[0] 1079 ih[0] = old ^ 0xFFFF 1080 1081 self.assertNotEqual(old, ih[0], 1082 "Setting new value to internal buffer failed")
1083 #/class TestIntelHex16bit 1084 1085
1086 -class TestIntelHexErrors(TestIntelHexBase):
1087 """Tests for custom errors classes""" 1088
1089 - def assertEqualExc(self, message, exception):
1090 return self.assertEqual(message, str(exception))
1091
1092 - def test_IntelHexError(self):
1093 self.assertEqualExc('IntelHex base error', IntelHexError())
1094
1095 - def test_IntelHexError_message(self):
1096 self.assertEqualExc('IntelHex custom error message', 1097 IntelHexError(msg='IntelHex custom error message')) 1098 self.assertEqualExc('IntelHex base error', IntelHexError(msg=''))
1099
1100 - def test_HexReaderError(self):
1101 self.assertEqualExc('Hex reader base error', HexReaderError())
1102
1103 - def test_HexRecordError(self):
1104 self.assertEqualExc('Hex file contains invalid record at line 1', 1105 HexRecordError(line=1))
1106
1107 - def test_RecordLengthError(self):
1108 self.assertEqualExc('Record at line 1 has invalid length', 1109 RecordLengthError(line=1))
1110
1111 - def test_RecordTypeError(self):
1112 self.assertEqualExc('Record at line 1 has invalid record type', 1113 RecordTypeError(line=1))
1114
1115 - def test_RecordChecksumError(self):
1116 self.assertEqualExc('Record at line 1 has invalid checksum', 1117 RecordChecksumError(line=1))
1118
1119 - def test_EOFRecordError(self):
1120 self.assertEqualExc('File has invalid End-of-File record', 1121 EOFRecordError())
1122
1124 self.assertEqualExc( 1125 'Invalid Extended Segment Address Record at line 1', 1126 ExtendedSegmentAddressRecordError(line=1))
1127
1129 self.assertEqualExc('Invalid Extended Linear Address Record at line 1', 1130 ExtendedLinearAddressRecordError(line=1))
1131
1133 self.assertEqualExc('Invalid Start Segment Address Record at line 1', 1134 StartSegmentAddressRecordError(line=1))
1135
1137 self.assertEqualExc('Invalid Start Linear Address Record at line 1', 1138 StartLinearAddressRecordError(line=1))
1139
1141 self.assertEqualExc('Start Address Record appears twice at line 1', 1142 DuplicateStartAddressRecordError(line=1))
1143
1145 self.assertEqualExc("Invalid start address value: {'foo': 1}", 1146 InvalidStartAddressValueError(start_addr={'foo': 1}))
1147
1148 - def test_AddressOverlapError(self):
1149 self.assertEqualExc('Hex file has data overlap at address 0x1234 ' 1150 'on line 1', 1151 AddressOverlapError(address=0x1234, line=1))
1152
1153 - def test_NotEnoughDataError(self):
1154 self.assertEqualExc('Bad access at 0x1234: ' 1155 'not enough data to read 10 contiguous bytes', 1156 intelhex.NotEnoughDataError(address=0x1234, length=10))
1157
1158 - def test_BadAccess16bit(self):
1159 self.assertEqualExc('Bad access at 0x1234: ' 1160 'not enough data to read 16 bit value', 1161 BadAccess16bit(address=0x1234))
1162 #/class TestIntelHexErrors 1163 1164
1165 -class TestDecodeHexRecords(TestIntelHexBase):
1166 """Testing that decoding of records is correct 1167 and all errors raised when needed 1168 """ 1169
1170 - def setUp(self):
1171 self.ih = IntelHex() 1172 self.decode_record = self.ih._decode_record
1173
1174 - def tearDown(self):
1175 del self.ih
1176
1177 - def test_empty_line(self):
1178 # do we could to accept empty lines in hex files? 1179 # standard don't say anything about this 1180 self.decode_record('')
1181
1182 - def test_non_empty_line(self):
1183 self.assertRaisesMsg(HexRecordError, 1184 'Hex file contains invalid record at line 1', 1185 self.decode_record, 1186 ' ', 1187 1)
1188
1189 - def test_short_record(self):
1190 # if record too short it's not a hex record 1191 self.assertRaisesMsg(HexRecordError, 1192 'Hex file contains invalid record at line 1', 1193 self.decode_record, 1194 ':', 1195 1)
1196
1197 - def test_odd_hexascii_digits(self):
1198 self.assertRaisesMsg(HexRecordError, 1199 'Hex file contains invalid record at line 1', 1200 self.decode_record, 1201 ':0100000100F', 1202 1)
1203
1204 - def test_invalid_length(self):
1205 self.assertRaisesMsg(RecordLengthError, 1206 'Record at line 1 has invalid length', 1207 self.decode_record, 1208 ':FF00000100', 1209 1)
1210
1211 - def test_invalid_record_type(self):
1212 self.assertRaisesMsg(RecordTypeError, 1213 'Record at line 1 has invalid record type', 1214 self.decode_record, 1215 ':000000FF01', 1216 1)
1217
1218 - def test_invalid_checksum(self):
1219 self.assertRaisesMsg(RecordChecksumError, 1220 'Record at line 1 has invalid checksum', 1221 self.decode_record, 1222 ':0000000100', 1223 1)
1224
1225 - def test_invalid_eof(self):
1226 self.assertRaisesMsg(EOFRecordError, 1227 'File has invalid End-of-File record', 1228 self.decode_record, 1229 ':0100000100FE', 1230 1)
1231
1233 # length 1234 self.assertRaisesMsg(ExtendedSegmentAddressRecordError, 1235 'Invalid Extended Segment Address Record at line 1', 1236 self.decode_record, 1237 ':00000002FE', 1238 1) 1239 # addr field 1240 self.assertRaisesMsg(ExtendedSegmentAddressRecordError, 1241 'Invalid Extended Segment Address Record at line 1', 1242 self.decode_record, 1243 ':020001020000FB', 1244 1)
1245
1247 # length 1248 self.assertRaisesMsg(ExtendedLinearAddressRecordError, 1249 'Invalid Extended Linear Address Record ' 1250 'at line 1', 1251 self.decode_record, 1252 ':00000004FC', 1253 1) 1254 # addr field 1255 self.assertRaisesMsg(ExtendedLinearAddressRecordError, 1256 'Invalid Extended Linear Address Record ' 1257 'at line 1', 1258 self.decode_record, 1259 ':020001040000F9', 1260 1)
1261
1263 # length 1264 self.assertRaisesMsg(StartSegmentAddressRecordError, 1265 'Invalid Start Segment Address Record at line 1', 1266 self.decode_record, 1267 ':00000003FD', 1268 1) 1269 # addr field 1270 self.assertRaisesMsg(StartSegmentAddressRecordError, 1271 'Invalid Start Segment Address Record at line 1', 1272 self.decode_record, 1273 ':0400010300000000F8', 1274 1)
1275
1277 self.decode_record(':0400000312345678E5') 1278 self.assertRaisesMsg(DuplicateStartAddressRecordError, 1279 'Start Address Record appears twice at line 2', 1280 self.decode_record, 1281 ':0400000300000000F9', 1282 2)
1283
1285 # length 1286 self.assertRaisesMsg(StartLinearAddressRecordError, 1287 'Invalid Start Linear Address Record at line 1', 1288 self.decode_record, 1289 ':00000005FB', 1290 1) 1291 # addr field 1292 self.assertRaisesMsg(StartLinearAddressRecordError, 1293 'Invalid Start Linear Address Record at line 1', 1294 self.decode_record, 1295 ':0400010500000000F6', 1296 1)
1297
1299 self.decode_record(':0400000512345678E3') 1300 self.assertRaisesMsg(DuplicateStartAddressRecordError, 1301 'Start Address Record appears twice at line 2', 1302 self.decode_record, 1303 ':0400000500000000F7', 1304 2)
1305
1306 - def test_addr_overlap(self):
1307 self.decode_record(':0100000000FF') 1308 self.assertRaisesMsg(AddressOverlapError, 1309 'Hex file has data overlap at address 0x0 ' 1310 'on line 1', 1311 self.decode_record, 1312 ':0100000000FF', 1313 1)
1314
1315 - def test_data_record(self):
1316 # should be no exceptions 1317 self.decode_record(':0100000000FF\n') 1318 self.decode_record(':03000100000102F9\r\n') 1319 self.decode_record(':1004E300CFF0FBE2FDF220FF20F2E120E2FBE6F396')
1320
1321 - def test_eof(self):
1322 # EOF should raise special exception 1323 self.assertRaises(_EndOfFile, self.decode_record, ':00000001FF')
1324 1325 #/class TestDecodeHexRecords 1326 1327
1328 -class TestHex2Bin(unittest.TestCase):
1329
1330 - def setUp(self):
1331 self.fin = StringIO(hex8) 1332 self.fout = StringIO()
1333
1334 - def tearDown(self):
1335 self.fin.close() 1336 self.fout.close()
1337
1338 - def test_hex2bin(self):
1339 ih = hex2bin(self.fin, self.fout) 1340 data = array.array('B', self.fout.getvalue()) 1341 for addr in xrange(len(bin8)): 1342 expected = bin8[addr] 1343 actual = data[addr] 1344 self.assertEqual(expected, actual, 1345 "Data different at address " 1346 "%x (%x != %x)" % (addr, expected, actual))
1347 1348
1349 -class TestBuildRecords(TestIntelHexBase):
1350
1351 - def test__from_bytes(self):
1352 self.assertEqual(':00000001FF', 1353 intelhex.Record._from_bytes([0,0,0,1]))
1354
1355 - def test_data(self):
1356 self.assertEqual(':011234005663', intelhex.Record.data(0x1234, [0x56])) 1357 self.assertEqual(':0312340056789059', 1358 intelhex.Record.data(0x1234, [0x56, 0x78, 0x90]))
1359
1360 - def test_eof(self):
1361 self.assertEqual(':00000001FF', intelhex.Record.eof())
1362
1364 self.assertEqual(':020000021234B6', 1365 intelhex.Record.extended_segment_address(0x1234))
1366
1367 - def test_start_segment_address(self):
1368 self.assertEqual(':0400000312345678E5', 1369 intelhex.Record.start_segment_address(0x1234, 0x5678))
1370
1372 self.assertEqual(':020000041234B4', 1373 intelhex.Record.extended_linear_address(0x1234))
1374
1375 - def test_start_linear_address(self):
1376 self.assertEqual(':0400000512345678E3', 1377 intelhex.Record.start_linear_address(0x12345678))
1378 1379
1380 -class Test_GetFileAndAddrRange(TestIntelHexBase):
1381
1382 - def test_simple(self):
1383 self.assertEqual(('filename.hex', None, None), 1384 intelhex._get_file_and_addr_range('filename.hex')) 1385 self.assertEqual(('f', None, None), 1386 intelhex._get_file_and_addr_range('f')) 1387 self.assertEqual(('filename.hex', 1, None), 1388 intelhex._get_file_and_addr_range('filename.hex:1:')) 1389 self.assertEqual(('filename.hex', None, 10), 1390 intelhex._get_file_and_addr_range('filename.hex::A')) 1391 self.assertEqual(('filename.hex', 1, 10), 1392 intelhex._get_file_and_addr_range('filename.hex:1:A')) 1393 self.assertEqual(('filename.hex', 1, 10), 1394 intelhex._get_file_and_addr_range('filename.hex:0001:000A'))
1395
1396 - def test_bad_notation(self):
1397 self.assertRaises(intelhex._BadFileNotation, 1398 intelhex._get_file_and_addr_range, 'filename.hex:') 1399 self.assertRaises(intelhex._BadFileNotation, 1400 intelhex._get_file_and_addr_range, 'filename.hex:::') 1401 self.assertRaises(intelhex._BadFileNotation, 1402 intelhex._get_file_and_addr_range, 'C:\\filename.hex:', True)
1403
1404 - def test_drive_letter(self):
1405 self.assertEqual(('C:\\filename.hex', None, None), 1406 intelhex._get_file_and_addr_range('C:\\filename.hex', True)) 1407 self.assertEqual(('C:\\filename.hex', 1, None), 1408 intelhex._get_file_and_addr_range('C:\\filename.hex:1:', True)) 1409 self.assertEqual(('C:\\filename.hex', None, 10), 1410 intelhex._get_file_and_addr_range('C:\\filename.hex::A', True)) 1411 self.assertEqual(('C:\\filename.hex', 1, 10), 1412 intelhex._get_file_and_addr_range('C:\\filename.hex:1:A', True)) 1413 self.assertEqual(('C:\\filename.hex', 1, 10), 1414 intelhex._get_file_and_addr_range('C:\\filename.hex:0001:000A', True))
1415 1416 1417 ## 1418 # MAIN 1419 if __name__ == '__main__': 1420 unittest.main() 1421