Repository: canonical/operator

Issue:
Harness.Container.get_services() does not seem correctly mocked
I think this test should work, but it does not with `ops 1.3.0`:

```
    def test_mocked_get_services(self):
        self.harness.begin()
        traefik_container = self.harness.charm.unit.get_container("traefik")
        traefik_container.add_layer("traefik_layer", {
            "summary": "Traefik layer",
            "description": "Pebble config layer for Traefik",
            "services": {
                "traefik": {
                    "override": "replace",
                    "summary": "Traefik",
                    "command": "/usr/bin/traefik",
                },
            },
        })

        assert traefik_container.get_service("traefik")  # So far, so good
        assert "traefik" in traefik_container.get_services()  # FAILS, `traefik_container.get_services()` returns {} 
```

Discussion:
rwcarlsen: The other option is to go into the pebble regular and test clients and make them treat an empty list the same as a None arg.  Not sure which approach is better.  Opinions welcome.
benhoyt: Note that the `canonical/grafana-operator` tests are failing due to https://github.com/canonical/grafana-k8s-operator/pull/68. I've hacked around that in https://github.com/canonical/operator/pull/668/files#diff-d899f68301edb06393d5435313801f676fc892f1484aa76f10d82c36e5e022f2R26

Patch:
diff --git a/ops/model.py b/ops/model.py
index 9974af9..e627951 100644
--- a/ops/model.py
+++ b/ops/model.py
@@ -1194,6 +1194,7 @@ class Container:
         If no service names are specified, return status information for all
         services, otherwise return information for only the given services.
         """
+        service_names = service_names or None
         services = self._pebble.get_services(service_names)
         return ServiceInfoMapping(services)
 


Test patch:
diff --git a/test/test_model.py b/test/test_model.py
index c8e890f..5004d88 100755
--- a/test/test_model.py
+++ b/test/test_model.py
@@ -772,9 +772,26 @@ class TestApplication(unittest.TestCase):
             resources:
               foo: {type: file, filename: foo.txt}
               bar: {type: file, filename: bar.txt}
+            containers:
+              bar:
+                k: v
         ''')
         self.peer_rel_id = self.harness.add_relation('db2', 'db2')
         self.app = self.harness.model.app
+        self.addCleanup(self.harness.cleanup)
+
+    # Tests fix for https://github.com/canonical/operator/issues/694.
+    def test_mocked_get_services(self):
+        self.harness.begin()
+        c = self.harness.charm.unit.get_container('bar')
+        c.add_layer('layer1', {
+            'summary': 'layer',
+            'services': {"baz": {'override': 'replace', 'summary': 'echo', 'command': 'echo 1'}},
+        })
+
+        s = c.get_service('baz')  # So far, so good
+        self.assertTrue(s)
+        self.assertTrue('baz' in c.get_services())
 
     def test_planned_units(self):
         rel_id = self.peer_rel_id
@@ -1062,7 +1079,7 @@ containers:
         self.assertEqual(services['s2'].current, ops.pebble.ServiceStatus.INACTIVE)
 
         self.assertEqual(self.pebble.requests, [
-            ('get_services', ()),
+            ('get_services', None),
             ('get_services', ('s1', 's2')),
         ])