code: def test_effects(self):
      def get_effect_proto(obs, effect_id):
          for e in obs.observation.raw_data.effects:
              if e.effect_id == effect_id:
                  return e
          return None
  
      def get_effect_obs(obs, effect_id):
          for e in obs:
              if e.effect == effect_id:
                  return e
          return None
  
      self.god()
      self.move_camera(32, 32)
  
      # Create some sentries.
      self.create_unit(
          unit_type=units.Protoss.Sentry, owner=1, pos=(30, 30)
      )
      self.create_unit(
          unit_type=units.Protoss.Stalker, owner=1, pos=(28, 30)
      )
      self.create_unit(
          unit_type=units.Protoss.Phoenix, owner=2, pos=(30, 28)
      )
  
      self.step()
      obs = self.observe()
  
      # Give enough energy.
      sentry = utils.get_unit(obs[0], unit_type=units.Protoss.Sentry)
      stalker = utils.get_unit(obs[0], unit_type=units.Protoss.Stalker)
      pheonix = utils.get_unit(obs[0], unit_type=units.Protoss.Phoenix)
      self.set_energy(sentry.tag, 200)
      self.set_energy(pheonix.tag, 200)
  
      self.step()
      obs = self.observe()
  
      self.raw_unit_command(
          0, "Effect_GuardianShield_quick", sentry.tag
      )
  
      self.step(16)
      obs = self.observe()
  
      self.assertIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[0], tag=sentry.tag).buff_ids,
      )
      self.assertIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[1], tag=sentry.tag).buff_ids,
      )
      self.assertIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[0], tag=stalker.tag).buff_ids,
      )
      self.assertIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[1], tag=stalker.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[0], tag=pheonix.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GuardianShield,
          utils.get_unit(obs[1], tag=pheonix.tag).buff_ids,
      )
  
      # Both players should see the shield.
      e = get_effect_proto(obs[0], features.Effects.GuardianShield)
      self.assertIsNotNone(e)
      self.assert_point(e.pos[0], (30, 30))
      self.assertEqual(e.alliance, sc_raw.Self)
      self.assertEqual(e.owner, 1)
      self.assertGreater(e.radius, 3)
  
      e = get_effect_proto(obs[1], features.Effects.GuardianShield)
      self.assertIsNotNone(e)
      self.assert_point(e.pos[0], (30, 30))
      self.assertEqual(e.alliance, sc_raw.Enemy)
      self.assertEqual(e.owner, 1)
      self.assertGreater(e.radius, 3)
  
      # Should show up on the feature layers too.
      transformed_obs1 = self._features.transform_obs(obs[0])
      transformed_obs2 = self._features.transform_obs(obs[1])
      screen1 = transformed_obs1["feature_screen"]
      screen2 = transformed_obs2["feature_screen"]
      sentry_pos = utils.xy_locs(
          screen1.unit_type == units.Protoss.Sentry
      )[0]
      self.assert_layers(
          screen1,
          sentry_pos,
          unit_type=units.Protoss.Sentry,
          effects=features.Effects.GuardianShield,
          buffs=buffs.Buffs.GuardianShield,
      )
      self.assert_layers(
          screen2,
          sentry_pos,
          unit_type=units.Protoss.Sentry,
          effects=features.Effects.GuardianShield,
          buffs=buffs.Buffs.GuardianShield,
      )
      phoenix_pos = utils.xy_locs(
          screen1.unit_type == units.Protoss.Phoenix
      )[0]
      self.assert_layers(
          screen1,
          phoenix_pos,
          unit_type=units.Protoss.Phoenix,
          effects=features.Effects.GuardianShield,
          buffs=0,
      )
      self.assert_layers(
          screen2,
          phoenix_pos,
          unit_type=units.Protoss.Phoenix,
          effects=features.Effects.GuardianShield,
          buffs=0,
      )
  
      # Also in the raw_effects.
      raw1 = transformed_obs1["raw_effects"]
      e = get_effect_obs(raw1, features.Effects.GuardianShield)
      self.assertIsNotNone(e)
      # Not located at (30, 30) due to map shape and minimap coords.
      self.assertGreater(e.x, 20)
      self.assertGreater(e.y, 20)
      self.assertEqual(e.alliance, sc_raw.Self)
      self.assertEqual(e.owner, 1)
      self.assertGreater(e.radius, 3)
  
      self.raw_unit_command(
          1,
          "Effect_GravitonBeam_screen",
          pheonix.tag,
          target=stalker.tag,
      )
  
      self.step(32)
      obs = self.observe()
  
      self.assertIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[0], tag=stalker.tag).buff_ids,
      )
      self.assertIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[1], tag=stalker.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[0], tag=sentry.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[1], tag=sentry.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[0], tag=pheonix.tag).buff_ids,
      )
      self.assertNotIn(
          buffs.Buffs.GravitonBeam,
          utils.get_unit(obs[1], tag=pheonix.tag).buff_ids,
      )
  
file_path: pysc2/pysc2/tests/obs_test.py
imports: from absl.testing import absltest
  from pysc2.lib import actions
  from pysc2.lib import buffs
  from pysc2.lib import features
  from pysc2.lib import units
  from pysc2.tests import utils
  from s2clientprotocol import debug_pb2
  from s2clientprotocol import raw_pb2
label_desc: Use image node_id 6 for calling the ObsTest obj's underlying member method code with example usage: obj.test_effects() and returns: None, None, e, e