def test_general(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/general.yaml"))
        self.assertEqual(len(semconv.models), 2)

        expected = {
            "id":
            "network",
            "prefix":
            "net",
            "extends":
            "",
            "n_constraints":
            0,
            "attributes": [
                "net.transport",
                "net.peer.ip",
                "net.peer.port",
                "net.peer.name",
                "net.host.ip",
                "net.host.port",
                "net.host.name",
            ],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[0], expected)
        expected = {
            "id": "identity",
            "prefix": "enduser",
            "extends": "",
            "n_constraints": 0,
            "attributes": ["enduser.id", "enduser.role", "enduser.scope"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[1], expected)
    def test_populate_other_attributes(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/http.yaml"))
        semconv.parse(self.load_file("yaml/faas.yaml"))
        semconv.parse(self.load_file("yaml/general.yaml"))
        semconv.finish()
        models = sorted(semconv.models.values(), key=lambda m: m.semconv_id)
        self.assertEqual(len(models), 10)
        self.assertEqual(len(models[0].constraints), 0)
        self.assertEqual(len(models[1].constraints), 0)

        self.assertEqual(len(models[2].constraints), 2)
        self.assertTrue(isinstance(models[2].constraints[0], Include))
        self.assertEqual(len(models[2].constraints[1].choice_list_attributes),
                         4)

        self.assertEqual(len(models[3].constraints), 0)
        self.assertEqual(len(models[4].constraints), 0)
        self.assertEqual(len(models[5].constraints), 0)

        self.assertEqual(len(models[6].constraints), 1)
        self.assertEqual(len(models[6].constraints[0].choice_list_attributes),
                         4)

        self.assertEqual(len(models[7].constraints), 1)
        self.assertEqual(len(models[6].constraints[0].choice_list_attributes),
                         4)

        self.assertEqual(len(models[8].constraints), 0)
        self.assertEqual(len(models[9].constraints), 0)
 def test_id_clash(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("yaml/errors/id_clash/span_faas.yaml"))
     semconv.parse(
         self.load_file("yaml/errors/id_clash/resource_faas.yaml"))
     semconv.finish()
     self.assertTrue(semconv.errors)
 def test_event(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("yaml/event.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 1)
     event = list(semconv.models.values())[0]
     expected = {
         "id":
         "exception",
         "prefix":
         "exception",
         "extends":
         "",
         "n_constraints":
         1,
         "attributes": [
             "exception.type",
             "exception.message",
             "exception.stacktrace",
             "exception.escaped",
         ],
     }
     self.semantic_convention_check(event, expected)
     constraint = event.constraints[0]
     self.assertIsInstance(constraint, AnyOf)
     constraint: AnyOf
     for choice_index, attr_list in enumerate(constraint.choice_list_ids):
         for attr_index, attr in enumerate(attr_list):
             self.assertEqual(
                 event.attrs_by_name.get(attr),
                 constraint.choice_list_attributes[choice_index]
                 [attr_index],
             )
    def test_include(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/http.yaml"))
        semconv.parse(self.load_file("yaml/faas.yaml"))
        semconv.parse(self.load_file("yaml/general.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 10)

        faas_http = [s for s in semconv.models.values() if s.semconv_id == "faas.http"][
            0
        ]
        expected = {
            "id": "faas.http",
            "prefix": "faas",
            "extends": "faas",
            "n_constraints": 2,
            "attributes": [
                # Parent
                "faas.trigger",
                "faas.execution",
                # Include
                "http.method",
                "http.url",
                "http.target",
                "http.host",
                "http.scheme",
                "http.status_code",
                "http.status_text",
                "http.flavor",
                "http.user_agent",
                "http.server_name",
            ],
        }
        self.semantic_convention_check(faas_http, expected)
    def test_rpc(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/rpc.yaml"))
        self.assertEqual(len(semconv.models), 3)

        expected = {
            "id": "rpc",
            "prefix": "rpc",
            "extends": "",
            "n_constraints": 1,
            "attributes": ["rpc.service"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[0], expected)
        expected = {
            "id": "grpc.client",
            "prefix": "",
            "extends": "rpc",
            "n_constraints": 0,
            "attributes": ["net.peer.port"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[1], expected)
        expected = {
            "id": "grpc.server",
            "prefix": "",
            "extends": "rpc",
            "n_constraints": 0,
            "attributes": ["net.peer.port"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[2], expected)
Beispiel #7
0
 def test_parameter_remove_constraint(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(
         self.load_file(
             "markdown/parameter_remove_constraint/database.yaml"))
     semconv.parse(
         self.load_file(
             "markdown/parameter_remove_constraint/general.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 6)
     with open(
             self.load_file(
                 "markdown/parameter_remove_constraint/input.md"),
             "r") as markdown:
         content = markdown.read()
     with open(
             self.load_file(
                 "markdown/parameter_remove_constraint/expected.md"),
             "r") as markdown:
         expected = markdown.read()
     self.check_render(
         semconv,
         "markdown/parameter_remove_constraint/",
         "markdown/parameter_remove_constraint/input.md",
         content,
         expected,
     )
    def test_faas(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/faas.yaml"))
        self.assertEqual(len(semconv.models), 5)

        expected = {
            "id": "faas",
            "prefix": "faas",
            "extends": "",
            "n_constraints": 0,
            "attributes": ["faas.trigger", "faas.execution"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[0], expected)
        expected = {
            "id":
            "faas.datasource",
            "prefix":
            "faas.document",
            "extends":
            "faas",
            "n_constraints":
            0,
            "attributes": [
                "faas.document.collection",
                "faas.document.operation",
                "faas.document.time",
                "faas.document.name",
            ],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[1], expected)
        expected = {
            "id": "faas.http",
            "prefix": "",
            "extends": "faas",
            "n_constraints": 1,
            "attributes": [],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[2], expected)
        expected = {
            "id": "faas.pubsub",
            "prefix": "",
            "extends": "faas",
            "n_constraints": 0,
            "attributes": [],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[3], expected)
        expected = {
            "id": "faas.timer",
            "prefix": "faas",
            "extends": "faas",
            "n_constraints": 0,
            "attributes": ["faas.time", "faas.cron"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[4], expected)
 def test_markdown_link(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("yaml/links.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 1)
     s = list(semconv.models.values())[0]
     for attr in s.attributes:
         brief = attr.brief
         self.assertEqual(brief.raw_text, brief.__str__())
 def test_validate_anyof_attributes(self):
     with self.assertRaises(ValidationError) as ex:
         semconv = SemanticConventionSet(debug=False)
         semconv.parse(self.load_file("yaml/errors/validate_anyof.yaml"))
         semconv.finish()
     e = ex.exception
     msg = e.message.lower()
     self.assertIn("any_of attribute", msg)
     self.assertIn("does not exists", msg)
     self.assertEqual(e.line, 15)
Beispiel #11
0
 def test_missing_event(self):
     with self.assertRaises(ValidationError) as ex:
         semconv = SemanticConventionSet(debug=False)
         semconv.parse(
             self.load_file("yaml/errors/events/missing_event.yaml"))
         semconv.finish()
     e = ex.exception
     msg = e.message.lower()
     self.assertIn("as event but the latter cannot be found!", msg)
     self.assertEqual(e.line, 2)
    def test_extends_prefix(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/extends/http.yaml"))
        semconv.parse(self.load_file("yaml/extends/child.http.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 3)

        base = list(semconv.models.values())[1]
        child = list(semconv.models.values())[2]
        self.assertEqual(base.prefix, "http")
        self.assertEqual(child.prefix, "child.http")
Beispiel #13
0
def parse_semconv(args, parser) -> SemanticConventionSet:
    semconv = SemanticConventionSet(args.debug)
    find_yaml(args)
    for file in sorted(args.files):
        if not file.endswith(".yaml") and not file.endswith(".yml"):
            parser.error("{} is not a yaml file.".format(file))
        semconv.parse(file)
    semconv.finish()
    if semconv.has_error():
        sys.exit(1)
    return semconv
Beispiel #14
0
    def test_units(self):
        semconv = SemanticConventionSet(debug=True)
        semconv.parse(self.load_file("yaml/metrics/units.yaml"))
        semconv.finish()

        assert len(semconv.models) == 1

        content = self.read_file("markdown/metrics/units_input.md")
        expected = self.read_file("markdown/metrics/units_output.md")
        self.check_render(semconv, "markdown/metrics/",
                          "markdown/metrics/units_input.md", content, expected)
    def test_deprecation(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/deprecated/http.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 1)

        self.assertIsNotNone(list(semconv.models.values())[0].attributes[0].deprecated)
        self.assertEqual(
            list(semconv.models.values())[0].attributes[0].deprecated,
            "Use attribute `nonDepecrated`.",
        )
        self.assertIsNone(list(semconv.models.values())[0].attributes[3].deprecated)
Beispiel #16
0
 def test_wrong_event_type(self):
     with self.assertRaises(ValidationError) as ex:
         semconv = SemanticConventionSet(debug=False)
         semconv.parse(
             self.load_file("yaml/errors/events/no_event_type.yaml"))
         semconv.finish()
     e = ex.exception
     msg = e.message.lower()
     self.assertIn(
         "as event but the latter is not a semantic convention for events",
         msg)
     self.assertEqual(e.line, 2)
Beispiel #17
0
 def testExampleArray(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("markdown/example_array/http.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 1)
     with open(self.load_file("markdown/example_array/input.md"),
               "r") as markdown:
         content = markdown.read()
     with open(self.load_file("markdown/example_array/expected.md"),
               "r") as markdown:
         expected = markdown.read()
     self.check_render(semconv, "markdown/example_array/",
                       "markdown/example_array/input.md", content, expected)
    def test_ref(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/rpc.yaml"))
        semconv.parse(self.load_file("yaml/general.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 5)

        client = list(semconv.models.values())[1]
        server = list(semconv.models.values())[2]
        self.assertIsNotNone(client.attributes[1].ref)
        self.assertIsNotNone(client.attributes[1].attr_type)

        self.assertIsNotNone(server.attributes[1].ref)
        self.assertIsNotNone(server.attributes[1].attr_type)
    def test_numeric_attributes(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/numeric_attributes.yml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 1)

        expected = {
            "id": "test",
            "prefix": "test",
            "extends": "",
            "n_constraints": 0,
            "attributes": ["test.one", "test.two"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[0], expected)
Beispiel #20
0
def test_codegen_units(test_file_path, read_test_file):
    semconv = SemanticConventionSet(debug=False)
    semconv.parse(test_file_path("yaml", "metrics", "units.yaml"))
    semconv.finish()

    template_path = test_file_path("jinja", "metrics", "units_template")
    renderer = CodeRenderer({})

    output = io.StringIO()
    renderer.render(semconv, template_path, output, None)
    result = output.getvalue()

    expected = read_test_file("jinja", "metrics", "expected.java")

    assert result == expected
Beispiel #21
0
 def test_error_wrong_id(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("markdown/wrong_semconv_id/http.yaml"))
     semconv.parse(self.load_file("markdown/wrong_semconv_id/general.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 5)
     with open(self.load_file("markdown/wrong_semconv_id/input.md"),
               "r") as markdown:
         content = markdown.read()
     with self.assertRaises(Exception) as ex:
         renderer = MarkdownRenderer(
             self.load_file("markdown/wrong_semconv_id/"), semconv)
         renderer._render_single_file(content,
                                      "markdown/wrong_semconv_id/input.md",
                                      io.StringIO())
     self.assertEqual("Semantic Convention ID db not found",
                      ex.exception.args[0])
Beispiel #22
0
 def test_error_missing_end(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("markdown/missing_end_tag/http.yaml"))
     semconv.parse(self.load_file("markdown/missing_end_tag/general.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 5)
     with open(self.load_file("markdown/missing_end_tag/input.md"),
               "r") as markdown:
         content = markdown.read()
     with self.assertRaises(Exception) as ex:
         renderer = MarkdownRenderer(
             self.load_file("markdown/missing_end_tag/"), semconv)
         renderer._render_single_file(content,
                                      "markdown/missing_end_tag/input.md",
                                      io.StringIO())
     self.assertEqual("Missing ending <!-- endsemconv --> tag",
                      ex.exception.args[0])
Beispiel #23
0
    def testRef(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("markdown/ref/general.yaml"))
        semconv.parse(self.load_file("markdown/ref/rpc.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 5)
        md = self.load_file("markdown/ref/input/input_rpc.md")
        with open(md, "r") as markdown:
            content = markdown.read()
        renderer = MarkdownRenderer(self.load_file("markdown/ref/input"),
                                    semconv)
        output = io.StringIO()
        renderer._render_single_file(content, md, output)
        with open(self.load_file("markdown/ref/expected.md"), "r") as markdown:
            expected = markdown.read()

        assert output.getvalue() == expected
    def test_http(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/http.yaml"))
        self.assertEqual(len(semconv.models), 3)

        expected = {
            "id":
            "http",
            "prefix":
            "http",
            "extends":
            "",
            "n_constraints":
            0,
            "attributes": [
                "http.method",
                "http.url",
                "http.target",
                "http.host",
                "http.scheme",
                "http.status_code",
                "http.status_text",
                "http.flavor",
                "http.user_agent",
            ],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[0], expected)
        expected = {
            "id": "http.client",
            "prefix": "http",
            "extends": "http",
            "n_constraints": 1,
            "attributes": [],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[1], expected)
        expected = {
            "id": "http.server",
            "prefix": "http",
            "extends": "http",
            "n_constraints": 1,
            "attributes": ["http.server_name"],
        }
        self.semantic_convention_check(
            list(semconv.models.values())[2], expected)
    def test_stability(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/stability.yaml"))
        semconv.finish()
        self.assertEqual(len(semconv.models), 6)

        model = list(semconv.models.values())[0]
        self.assertEqual(len(model.attributes), 4)
        self.assertEqual(model.stability, None)

        attr = model.attributes[0]
        self.assertEqual(attr.attr_id, "exp_attr")
        self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL)

        attr = model.attributes[1]
        self.assertEqual(attr.attr_id, "stable_attr")
        self.assertEqual(attr.stability, StabilityLevel.STABLE)

        attr = model.attributes[2]
        self.assertEqual(attr.attr_id, "deprecated_attr")
        self.assertEqual(attr.stability, StabilityLevel.DEPRECATED)

        attr = model.attributes[3]
        self.assertEqual(attr.attr_id, "def_stability")
        self.assertEqual(attr.stability, StabilityLevel.STABLE)

        model = list(semconv.models.values())[1]
        self.assertEqual(len(model.attributes), 2)
        self.assertEqual(model.stability, StabilityLevel.EXPERIMENTAL)

        attr = model.attributes[0]
        self.assertEqual(attr.attr_id, "test_attr")
        self.assertEqual(attr.stability, StabilityLevel.EXPERIMENTAL)

        attr = model.attributes[1]
        self.assertEqual(attr.attr_id, "dep")
        self.assertEqual(attr.stability, StabilityLevel.DEPRECATED)

        model = list(semconv.models.values())[2]
        self.assertEqual(len(model.attributes), 1)
        self.assertEqual(model.stability, StabilityLevel.DEPRECATED)

        attr = model.attributes[0]
        self.assertEqual(attr.attr_id, "test_attr")
        self.assertEqual(attr.stability, StabilityLevel.DEPRECATED)
 def test_resource(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("yaml/cloud.yaml"))
     self.assertEqual(len(semconv.models), 1)
     cloud = list(semconv.models.values())[0]
     expected = {
         "id": "cloud",
         "prefix": "cloud",
         "extends": "",
         "n_constraints": 0,
         "attributes": [
             "cloud.provider",
             "cloud.account.id",
             "cloud.region",
             "cloud.zone",
         ],
     }
     self.semantic_convention_check(cloud, expected)
Beispiel #27
0
 def testSingle(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("markdown/single/http.yaml"))
     semconv.parse(self.load_file("markdown/single/general.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 5)
     with open(self.load_file("markdown/single/input.md"), "r") as markdown:
         content = markdown.read()
     with open(self.load_file("markdown/single/expected.md"),
               "r") as markdown:
         expected = markdown.read()
     self.check_render(
         semconv,
         "markdown/single/",
         "markdown/single/input.md",
         content,
         expected,
     )
 def test_span_with_event(self):
     semconv = SemanticConventionSet(debug=False)
     semconv.parse(self.load_file("yaml/event.yaml"))
     semconv.parse(self.load_file("yaml/span_event.yaml"))
     semconv.finish()
     self.assertEqual(len(semconv.models), 3)
     semconvs = list(semconv.models.values())
     self.assertTrue(isinstance(semconvs[0], EventSemanticConvention))
     self.assertTrue(isinstance(semconvs[1], SpanSemanticConvention))
     self.assertTrue(isinstance(semconvs[2], EventSemanticConvention))
     event_semconv = semconvs[1]
     self.assertEqual(2, len(event_semconv.events))
     self.assertTrue(
         isinstance(event_semconv.events[0], EventSemanticConvention))
     self.assertTrue(
         isinstance(event_semconv.events[1], EventSemanticConvention))
     self.assertEqual("exception", event_semconv.events[0].semconv_id)
     self.assertEqual("random.event", event_semconv.events[1].semconv_id)
    def test_database(self):
        semconv = SemanticConventionSet(debug=False)
        semconv.parse(self.load_file("yaml/database.yaml"))
        self.assertEqual(len(semconv.models), 1)

        expected = {
            "id": "database",
            "prefix": "db",
            "extends": "",
            "n_constraints": 1,
            "attributes": [
                "db.type",
                "db.instance",
                "db.statement",
                "db.url",
                "db.user",
            ],
        }
        self.semantic_convention_check(list(semconv.models.values())[0], expected)
    def check(
        self,
        input_dir: str,
        options=MarkdownOptions(),
        *,
        expected_name="expected.md",
        extra_yaml_dirs: Sequence[str] = (),
        assert_raises=None
    ) -> Optional[BaseException]:
        dirpath = Path(self.get_file_path(input_dir))
        if not dirpath.is_dir():
            raise ValueError(
                "Input dir does not exist (or is not a dir): " + str(dirpath)
            )
        semconv = SemanticConventionSet(debug=True)
        for fname in dirpath.glob("*.yaml"):
            print("Parsing", fname)
            semconv.parse(fname)
        for extra_dir in extra_yaml_dirs:
            for fname in Path(self.get_file_path(extra_dir)).glob("*.yaml"):
                print("Parsing", fname)
                semconv.parse(fname)

        semconv.finish()

        inputpath = dirpath / "input.md"

        output = io.StringIO()

        def do_render():
            renderer = MarkdownRenderer(str(dirpath), semconv, options)
            renderer._render_single_file(
                inputpath.read_text(encoding="utf-8"), str(inputpath), output
            )

        if assert_raises:
            with self.assertRaises(assert_raises) as ex:
                do_render()
            return ex.exception
        do_render()
        result = output.getvalue()
        assert result == (dirpath / expected_name).read_text(encoding="utf-8")
        return None