diff --git a/labgrid/remote/client.py b/labgrid/remote/client.py index 069240b9e..23da5bb97 100755 --- a/labgrid/remote/client.py +++ b/labgrid/remote/client.py @@ -506,6 +506,17 @@ def get_place_names_from_env(self): return places + def get_place_names_to_operate_on(self): + """Returns the place names acquire/release should operate on. + + An explicitly requested place (via -p/--place, LG_PLACE or PLACE) always + wins, even when an environment config is given. Only without one do we + operate on every RemotePlace of the environment. + """ + if self.env and not getattr(self.args, "explicit_place", False): + return self.get_place_names_from_env() + return [self.args.place] + def get_idle_place(self, place=None): place = self.get_place(place) if place.acquired: @@ -710,7 +721,7 @@ def check_matches(self, place): async def acquire(self): errors = [] - places = self.get_place_names_from_env() if self.env else [self.args.place] + places = self.get_place_names_to_operate_on() for place in places: try: await self._acquire_place(place) @@ -770,7 +781,7 @@ async def _acquire_place(self, place): async def release(self): errors = [] - places = self.get_place_names_from_env() if self.env else [self.args.place] + places = self.get_place_names_to_operate_on() for place in places: try: await self._release_place(place) @@ -2275,6 +2286,10 @@ def main(): if args.place is None: args.place = place + # remember whether the user explicitly selected a place, so that env-wide + # commands can be restricted to it + args.explicit_place = args.place is not None + if args.state is None: args.state = state diff --git a/tests/test_client.py b/tests/test_client.py index 8d2cc1c9f..9fd556de5 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -205,6 +205,41 @@ def test_place_acquire_multiple(create_place, tmpdir): spawn.expect('User.*Host.*Place.*Changed\r\n') assert not spawn.before, spawn.before +def test_place_acquire_with_env_and_place(create_place, tmpdir): + # create multiple places + place_names = ['test1', 'test2'] + for place_name in place_names: + create_place(place_name) + + # create env config with multiple RemotePlaces + p = tmpdir.join('config.yaml') + p.write('targets:') + for place_name in place_names: + p.write( + f""" + {place_name}: + resources: + RemotePlace: + name: {place_name} + """, + mode='a', + ) + + # -p must restrict the env-wide acquire to that single place + with pexpect.spawn(f'python -m labgrid.remote.client -c {p} -p test2 acquire') as spawn: + spawn.expect(pexpect.EOF) + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn('python -m labgrid.remote.client who') as spawn: + spawn.expect(pexpect.EOF) + assert b'test2' in spawn.before + assert b'test1' not in spawn.before + assert spawn.exitstatus == 0, spawn.before.strip() + + with pexpect.spawn(f'python -m labgrid.remote.client -c {p} -p test2 release') as spawn: + spawn.expect(pexpect.EOF) + assert spawn.exitstatus == 0, spawn.before.strip() + def test_place_acquire_enforce(place): with pexpect.spawn('python -m labgrid.remote.client -p test add-match does/not/exist') as spawn: spawn.expect(pexpect.EOF)