FitTestTool Very Strict, or Just Unreliable?

I'm generating FIT Activity files that seem to be perfectly suitable for Garmin upload as well as processing by Runanalyze.com.  The FitTestTool can't seem to get past the first 3 to 4 messages before crashing with a Java array index out-of-bounds exception.  It declares index 255 to be illegal.  From the traceback, line 885 of Decode.Java is:

....  fieldData[fieldDataIndex++] = data;

fieldDataIndex is incrementing wildly.   It is as if the logic leading up to this has somehow gotten lost with the number of definition fields I specified and just keeps trying to accumulate more definitions.

FitTestTool's output subsequently claims "Message Count: 3", which has some ambiguity as to which definition message it was processing at the time, but I think it almost has to be the DEVELOPER_DATA_ID definition.

After the FIT header, I have a FILE_ID definition that specifies 6 fields describing 15 data bytes, followed by the FILE_ID data message of 15 bytes, followed by a DEVELOPER_DATA_ID definition for 3 fields describing 37 data bytes.  Like so (little-endian):

0e 10 87 08 52 66 01 00 2e 46 49 54 31 45 //FIT Header

40 00 00 00 00  06   03 04 8c   04 04 86   01 02 84   02 02 84   05 02 84   00 01 00 //Define local '0' for global '0' (FILE_ID)
00   01 00 00 00  8a 3d 38 3d   ff 00   01 00   ff ff   04 //Local '0' data

43 00 00 cf 00  03   01 20 07  04 04 86  03 01 02 //Define local '3' for global 207 (DEVELOPER_DATA_ID)
03  ...  //Local '3' data ...

Is it using some other reference for the quantity of fields it expects for the DEVELOPER_DATA_ID definition message and ignoring the '3' I specified?  I didn't find anything in the FIT spec to justify that, nor does Garmin's processing of my upload seem to perform similarly.

I suppose I can ignore it in light of successful uploads, but I was hoping the tool might reveal any other problems with actual content that I might have.

  • The Test Tool is using the standard Java Decode class that all users of the Java SDK are using. The tool decodes the file and then inspects the decoded messages. If the tool is not able to decode the file without error, then I would suspect anyone using the Java SDK cannot decode the file without error either.

    The tool itself is not crashing, rather it is printing out the stack trace when an exception occurs while decoding the file. The tool will then inspect the messages it was able to successfully decode. The source code for the tool is available in the SDK, so you can see what it is doing. The real work happens in the plugin.

    /path/to/fit/sdk/java/com/garmin/fit/plugins/examples/ActivityFileValidationExample.java

    /path/to/fit/sdk/java/com/garmin/fit/plugins/ActivityFileValidationPlugin.java

    The tool looks for a handful of messages to be present, and then inspects a handful of fields in those messages. It is mostly performing a sanity check on the timestamps and message indexes along with a few other things. Sessions, Laps, and Records are all correlated by start and end time, which is what the tool is focused on. The tool does not look at the developer data messages or fields.

    Other than handling exceptions thrown from Decode.read(), the tool is not validating the binary format of the file. It leaves that to the Decode class. The assumption is that mostly corrupt or invalid files will be run through the tool, which is why the tool catches exceptions that occur during decoding, validates the messages that were found, and the prints a report of what was good and bad.

  • - since I had hundreds of messages in the file, the tool's "Message Count: 3" output is where I got the idea that the tool crashed.  I have since found that I did have a definition message claiming more fields than actually existed, so the tool couldn't find the proper start of the intended subsequent message.  It remains something of a mystery and a source of awe how runanalyze's algorithm was not deceived.