cpp-sc2 / cpp-sc2

StarCraft II Client C++ library, proud fork of Blizzard/s2client-api.
MIT License
48 stars 32 forks source link

WSL2 all_tests.exe fails #146

Open Nickrader opened 1 month ago

Nickrader commented 1 month ago

Workaround

Copy maps folder in project to maps folder in Windows https://aiarena.net/wiki/maps/


Map paths problem.

Not sure how he got it to work? https://github.com/cpp-sc2/cpp-sc2/commit/670972075050fe905f9cef8ec8f377a7ae01342b#diff-af936db1633489b017d1e45a55448545529ebc354aeb40eda83af5db7317a6e1R161 Error:

root@DESKTOP-4EN0ECU:~/cpp-sc2# ./build/bin/all_tests.exe
Running test: sc2::TestAbilityRemap
Launched SC2 (C:\Program Files (x86)\StarCraft II\Versions\Base92440\SC2_x64.exe), PID: 1792
Connecting to 127.0.0.1:8167...
Failed to establish websocket connection: connect(127.0.0.1:8167): timeout
Failed to establish websocket connection: connect(127.0.0.1:8167): timeout
Connected to 127.0.0.1:8167
CreateGame request returned an error code: Invalid Map Path
CreateGame request returned error details: map_path '\\wsl.localhost\Ubuntu\root\cpp-sc2\map
s\Test/Empty.SC2Map' file doesn't exist.
Failed to create game.

The map path is hardcoded to the project directory as a unix path separator, / {Test/Empty.SC2Map}.
https://github.com/cpp-sc2/cpp-sc2/blob/998ca3b1d40013ebb774120787daade8f5f227ea/src/sc2api/sc2_game_settings.cc#L28

When I change the source to use a Windows path separator, it reports Invalid Map Path, even though I can list the file using that path.

Coding path (sc2::kMapEmpty) with \ and copying map to my user created Windows maps, C:\Program Files (x86)\StarCraft II\Maps\ {https://aiarena.net/wiki/maps/} gives error, mangling the map path constant:

CreateGame request returned an error code: Invalid Map Path
CreateGame request returned error details: map_path 'C:\Program Files (x86)\StarCraft II\Map
s\Testpty.SC2Map' file doesn't exist.

Solution:

Supply path to bot, using Windows maps. https://aiarena.net/wiki/maps/ For all_tests.exe copy map to Windows & escape directory path separator. i.e. Test\\Empty.SC2Map

Other: Maybe because I'm running WSL as root and didn't create a user? IDK, maybe one day I'll dig deeper, but seems a WSL oddity because Powershell is able to find.

PS C:\Users\nickr> ls \\wsl.localhost\Ubuntu\root\cpp-sc2\maps\Test\Empty.SC2Map

    Directory: \\wsl.localhost\Ubuntu\root\cpp-sc2\maps\Test

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
------         7/19/2024   3:40 AM          23792 Empty.SC2Map

https://github.com/Nickrader/cpp-sc2/tree/fix-wsl2_paths

alkurbatov commented 1 month ago

AFAIK this map should be part of the project and must be included directly during tests run without necessity to copy it somewhere. Also, it work ok macOS. I believe the actual problem here is the path used to read the map: '\wsl.localhost\Ubuntu\root\cpp-sc2\map s\Test/Empty.SC2Map'. This is some mountpoint which could be not available to all_tests.exe or may require additional tweaking. Unfortunately without running WSL2 I can't tell what exactly got wrong.

Could you please provide additional info:

Nickrader commented 1 month ago

Yes, map is part of project, it's just my workaround involves some edits.

I'm guessing I have some configuration differences in WSL. Need to do more testing. His prompt is showing that of typical user: $ When I installed from Microsoft store (iirc) it defaulted to be root: #

So my fist step is setting up a user, because it was just easier to keep defaults. My next step would be to install another instance My guess at the moment is it's just WSL default configs changed in last 2 years, or we installed WSL different ways, or I messed something up. It worked fine all other ways last I tried: Windows, Linux, WineLinux.

Nickrader commented 1 month ago

Suspect is WSL config problem by user. Will re-open if any changes seem warranted.

Nickrader commented 1 month ago

User Error:
Running WSL as root, will create permissions conflicts in the project files. Build project as a user other than root.

Nickrader commented 1 month ago

Well, now it will run as root? I did cleanup my firewall settings so maybe that had something to do with it?

alkurbatov commented 1 month ago

Well, now it will run as root? I did cleanup my firewall settings so maybe that had something to do with it?

This is not permissions problem because you are running as root (i.e. has fool access to everything) and because the errors says "file doesn't exist". For lack of permissions it'll say something like "permission denied" or "access denied".

Neither this is firewall-related issue cause we don't do any network requests.

The issue could be because of the way the path to the provided file resolved. You see you have a kind of mountpoint in \wsl.localhost\Ubuntu\root\cpp-sc2\ , this is absolute path. However, when we run the test we use relative path (illustrated in the following pseudo code):

const char* kMapEmpty = "Test/Empty.SC2Map";

coordinator.StartGame(sc2::kMapEmpty)

As you can see this path is truncated and should be at least "maps/Test/Empty.SC2Map".

The trick is that the API has some path resolving logic located in ControlImp::ResolveMap and does several checks to find out what to do with the provided path and several manipulations with the path itself. Since we are running on linux inside WSL I assume that ControlImp::ResolveMap works wrong and as a result we have mixed slashes (please pay attention to the tail '\wsl.localhost\Ubuntu\root\cpp-sc2\maps\Test/Empty.SC2Map') which could work on windows (as windows has long story of slashes wars and finally accepts both even mixed in single string), but not on linux.

As a quick fix in the tests I think we can provide full relative path to the map e.g. assuming that the tests are launched from the root of the project:

const char* kMapEmpty = "./maps/Test/Empty.SC2Map";

A better fix could be a command-line flag which provides path to the map folder. An even better fix would be to put the maps inside the tests folder and adjusts the paths accordingly.

And the best solution I believe could be introduction of a variable SC2MAPPATH which should contain absolute or relative path to the maps folder. This solution allows to not only to fix the test but improve the overall API's logic because now the API does several "back jumps" in the path string to get to the users home and assumes particular path deep (see the implementation of GetGameMapsDirectory for windows and macOS/linux) which looks crazy to me.

However, the issue could also happen during basic run (e.g. we are trying to run inside WSL with linux client).

Nickrader commented 1 month ago

Thanks for the info.

Got it recreated. I forgot I still had the Maps folder in c:\Program Files (x86)\Starcraft II\ (so I moved it) The program was finding maps now without modifying source, but it was the Windows maps.

So now that it didn't find that I get the error about not finding the project included map. CreateGame request returned error details: map_path '\\wsl.localhost\Ubuntu\root\cpp-sc2\maps\Ladder/(2)Bel'ShirVestigeL E (Void).SC2Map' file doesn't exist.

As root or as admin user. So perhaps jrtknauer had a Maps folder in his Windows starcraft install too?

I normally don't use WSL at all, so I'll probably wait till someone has a problem to go any farther.

alkurbatov commented 1 month ago

That's a bit different thing: seems that you are trying to run one of example bots. For example bots similar map finding logic is used, but it looks for another embedded map.

Nickrader commented 1 month ago

My mistake,

homer@DESKTOP-4EN0ECU:~/cpp-sc2$ ./build/bin/all_tests.exe
Running test: sc2::TestAbilityRemap
Launched SC2 (C:\Program Files (x86)\StarCraft II\Versions\Base92440\SC2_x64.exe), PID: 8324
Connecting to 127.0.0.1:8167...
Failed to establish websocket connection: connect(127.0.0.1:8167): timeout
Connected to 127.0.0.1:8167
CreateGame request returned an error code: Invalid Map Path
CreateGame request returned error details: map_path '\\wsl.localhost\Ubuntu\home\homer\cpp-s
c2\maps\Test/Empty.SC2Map' file doesn't exist.
Failed to create game.

My assumption is when original WSL docs were written, they probably had a /maps folder in Windows. If I copy the contents of /maps from project to C:\Program Files (x86)\Maps\ all runs well. I think easiest solution is just to amend documents, advising to copy over maps for WSL users.