1from unittest import TestCase 2 3from ddtrace import config 4from ddtrace.pin import Pin 5from ddtrace.settings import IntegrationConfig 6 7 8class InstanceConfigTestCase(TestCase): 9 """TestCase for the Configuration API that is used to define 10 global settings and for each `Pin` instance. 11 """ 12 13 def setUp(self): 14 class Klass(object): 15 """Helper class where a Pin is always attached""" 16 17 pass 18 19 # define the Class and attach a Pin to it 20 self.Klass = Klass 21 Pin(service="metrics").onto(Klass) 22 23 def test_configuration_get_from(self): 24 # ensure a dictionary is returned 25 cfg = config.get_from(self.Klass) 26 assert isinstance(cfg, dict) 27 28 def test_configuration_get_from_twice(self): 29 # ensure the configuration is the same if `get_from` is used 30 # in the same instance 31 instance = self.Klass() 32 cfg1 = config.get_from(instance) 33 cfg2 = config.get_from(instance) 34 assert cfg1 is cfg2 35 36 def test_configuration_set(self): 37 # ensure the configuration can be updated in the Pin 38 instance = self.Klass() 39 cfg = config.get_from(instance) 40 cfg["distributed_tracing"] = True 41 assert config.get_from(instance)["distributed_tracing"] is True 42 43 def test_global_configuration_inheritance(self): 44 # ensure global configuration is inherited when it's set 45 cfg = config.get_from(self.Klass) 46 cfg["distributed_tracing"] = True 47 instance = self.Klass() 48 assert config.get_from(instance)["distributed_tracing"] is True 49 50 def test_configuration_override_instance(self): 51 # ensure instance configuration doesn't override global settings 52 global_cfg = config.get_from(self.Klass) 53 global_cfg["distributed_tracing"] = True 54 instance = self.Klass() 55 cfg = config.get_from(instance) 56 cfg["distributed_tracing"] = False 57 assert config.get_from(self.Klass)["distributed_tracing"] is True 58 assert config.get_from(instance)["distributed_tracing"] is False 59 60 def test_service_name_for_pin(self): 61 # ensure for backward compatibility that changing the service 62 # name via the Pin object also updates integration config 63 Pin(service="intake").onto(self.Klass) 64 instance = self.Klass() 65 cfg = config.get_from(instance) 66 assert cfg["service_name"] == "intake" 67 68 def test_service_attribute_priority(self): 69 # ensure the `service` arg has highest priority over configuration 70 # for backward compatibility 71 global_config = { 72 "service_name": "primary_service", 73 } 74 Pin(service="service", _config=global_config).onto(self.Klass) 75 instance = self.Klass() 76 cfg = config.get_from(instance) 77 assert cfg["service_name"] == "service" 78 79 def test_configuration_copy(self): 80 # ensure when a Pin is used, the given configuration is copied 81 global_config = { 82 "service_name": "service", 83 } 84 Pin(service="service", _config=global_config).onto(self.Klass) 85 instance = self.Klass() 86 cfg = config.get_from(instance) 87 cfg["service_name"] = "metrics" 88 assert global_config["service_name"] == "service" 89 90 def test_configuration_copy_upside_down(self): 91 # ensure when a Pin is created, it does not copy the given configuration 92 # until it's used for at least once 93 global_config = { 94 "service_name": "service", 95 } 96 Pin(service="service", _config=global_config).onto(self.Klass) 97 # override the global config: users do that before using the integration 98 global_config["service_name"] = "metrics" 99 # use the Pin via `get_from` 100 instance = self.Klass() 101 cfg = config.get_from(instance) 102 # it should have users updated value 103 assert cfg["service_name"] == "metrics" 104 105 def test_config_attr_and_key(self): 106 """ 107 This is a regression test for when mixing attr attribute and key 108 access we would set the value of the attribute but not the key 109 """ 110 integration_config = IntegrationConfig(config, "test") 111 112 # Our key and attribute do not exist 113 self.assertFalse(hasattr(integration_config, "distributed_tracing")) 114 self.assertNotIn("distributed_tracing", integration_config) 115 116 # Initially set and access 117 integration_config["distributed_tracing"] = True 118 self.assertTrue(integration_config["distributed_tracing"]) 119 self.assertTrue(integration_config.get("distributed_tracing")) 120 self.assertTrue(integration_config.distributed_tracing) 121 122 # Override by key and access 123 integration_config["distributed_tracing"] = False 124 self.assertFalse(integration_config["distributed_tracing"]) 125 self.assertFalse(integration_config.get("distributed_tracing")) 126 self.assertFalse(integration_config.distributed_tracing) 127 128 # Override by attr and access 129 integration_config.distributed_tracing = None 130 self.assertIsNone(integration_config["distributed_tracing"]) 131 self.assertIsNone(integration_config.get("distributed_tracing")) 132 self.assertIsNone(integration_config.distributed_tracing) 133