2

I am working on a test suite that also compare loads of paths, e.g. something like that:

expect(all_classes).to contain_exactly(
  File.expand_path("lib/#{plugin_info.actions_path}/#{plugin_name}_action.rb"),
  File.expand_path("lib/#{plugin_info.helper_path}/#{plugin_name}_helper.rb")
)

Unfortunately on Windows, this sometimes causes test failures if the generated temporary paths contain a directory, that triggers 8.3 filenames. An example:

2018-09-11T20:52:42.9346535Z   1) Fastlane::PluginGenerator#generate creates a plugin.rb file for the plugin
2018-09-11T20:52:42.9346797Z      Failure/Error:
2018-09-11T20:52:42.9347031Z        expect(all_classes).to contain_exactly(
2018-09-11T20:52:42.9347330Z          File.expand_path("lib/#{plugin_info.actions_path}/#{plugin_name}_action.rb"),
2018-09-11T20:52:42.9347673Z          File.expand_path("lib/#{plugin_info.helper_path}/#{plugin_name}_helper.rb")
2018-09-11T20:52:42.9347922Z        )
2018-09-11T20:52:42.9348040Z 
2018-09-11T20:52:42.9348443Z        expected collection contained:  ["C:/Users/VSSADM~1/AppData/Local/Temp/d20180911-3656-1muipt1/fastlane-plugin-tester_thing/lib/fastla...muipt1/fastlane-plugin-tester_thing/lib/fastlane/plugin/tester_thing/helper/tester_thing_helper.rb"]
2018-09-11T20:52:42.9349108Z        actual collection contained:    ["C:/Users/VssAdministrator/AppData/Local/Temp/d20180911-3656-1muipt1/fastlane-plugin-tester_thing/li...muipt1/fastlane-plugin-tester_thing/lib/fastlane/plugin/tester_thing/helper/tester_thing_helper.rb"]
2018-09-11T20:52:42.9349732Z        the missing elements were:      ["C:/Users/VSSADM~1/AppData/Local/Temp/d20180911-3656-1muipt1/fastlane-plugin-tester_thing/lib/fastla...muipt1/fastlane-plugin-tester_thing/lib/fastlane/plugin/tester_thing/helper/tester_thing_helper.rb"]
2018-09-11T20:52:42.9350359Z        the extra elements were:        ["C:/Users/VssAdministrator/AppData/Local/Temp/d20180911-3656-1muipt1/fastlane-plugin-tester_thing/li...muipt1/fastlane-plugin-tester_thing/lib/fastlane/plugin/tester_thing/helper/tester_thing_helper.rb"]
2018-09-11T20:52:42.9350855Z      # ./fastlane/spec/plugins_specs/plugin_generator_spec.rb:135:in `block (4 levels) in <top (required)>'
2018-09-11T20:52:42.9351199Z      # ./fastlane/spec/plugins_specs/plugin_generator_spec.rb:119:in `chdir'
2018-09-11T20:52:42.9351541Z      # ./fastlane/spec/plugins_specs/plugin_generator_spec.rb:119:in `block (3 levels) in <top (required)>'

In this case the problem lies in the path of the temp directory generated on a Azure DevOps pipelines machine: C:/Users/VssAdministrator/AppData/... vs. C:/Users/VSSADM~1/AppData/...

Some of the ruby methods seem to return the long version, some others the short one. Complicating it seems that the same methods sometimes return the one, and then the other - depending on some context I didn't understand yet, at least that is how it seems to me after debugging the test failures a bit.

Can someone explain to me what is going on and any ideas how I can fix this? Is there a way to "standardize" everything on one "method" of representing a path?
Anything else I should read or look at to fix this?

janpio
  • 10,645
  • 16
  • 64
  • 107
  • Oh, there might be a feature request for ruby from 2 years ago that would have fixed my problem: https://bugs.ruby-lang.org/issues/12656#change-70095 Unfortunately it wasn't merged (yet). – janpio Sep 12 '18 at 12:41
  • Can you explain why you would need this functionality tested? Obviously solving it is a bit more difficult but if we understood the context there might be a suitable workaround that would still meet your requirements – engineersmnky Sep 12 '18 at 14:49
  • For compatibility with legacy programs and scripts, the `TEMP` environment variable uses 8.3 DOS filenames, if they exist. For performance, NTFS can be configured to not create these legacy filenames, so on some systems it may contain "VssAdministrator" instead of "VSSADM~1", or whatever the generated short name turns out to be. It isn't always the same. It depends on collisions with existing filenames, and can even be set manually. – Eryk Sun Sep 12 '18 at 17:22
  • @engineersmnky Good question. Short: Because it is an existing text that I want to adapt to also work on Windows. Longer: In the specific example above the tool runs code to create some files. One includes a method that returns a list of the generated files. So this `expect` is used to confirm that the correct files were generated and the code that should return them actually does. You can look at it here: https://github.com/fastlane/fastlane/blob/e8787caf698667922ee061a0053b8f622b693057/fastlane/spec/plugins_specs/plugin_generator_spec.rb#L113-L144 – janpio Sep 12 '18 at 20:24
  • Interesting information @eryksun. The path here is created with `Dir.mktmpdir`. Does this use `TEMP`? Both the path with `VssAdministrator` and `VSSADM~1` are generated on the same system, in the same script (which I just couldn't understand enough yet to pinpoint it to a specific ruby method - might be different ones are used to create the both sides of the comparison). – janpio Sep 12 '18 at 20:33
  • 2
    The code that yields "VSSADM~1" is very likely using the value of `TEMP` or from [`GetTempPath`](https://learn.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-gettemppathw) directly. The other code is probably calling [`GetLongPathName`](https://learn.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getlongpathnamew). Doing this manually in Ruby will probably require an FFI (foreign function interface) call. I don't use Ruby to know what that would entail. In Python we have ctypes or cffi for this. – Eryk Sun Sep 12 '18 at 20:46
  • That would be pretty simple with ruby at least: https://stackoverflow.com/questions/10224572/convert-long-filename-to-short-filename-8-3/10244481#10244481 (also works with `GetLongPathName` of course). Problem is that I really don't want to add any (or "to much") platform specific code - I would really prefer to "just make it work" by e.g. setting a config value or similar. Seems I have to understand the code on a deeper level :/ – janpio Sep 12 '18 at 20:50
  • Have you tried if `File.expand_path(path)` or `Pathname.new(path).realpath` gives some sort of normalized path? – Kimmo Lehto Sep 13 '18 at 08:15

0 Answers0