-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] created integration tests for newhdrgen #97361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- added sorting to script so C headers are outputted in alpha order
- added sorting to script so C headers are outputted in alpha order
@llvm/pr-subscribers-libc Author: None (aaryanshukla) Changes
Full diff: https://github.com/llvm/llvm-project/pull/97361.diff 5 Files Affected:
diff --git a/libc/newhdrgen/tests/expected_output/string.h b/libc/newhdrgen/tests/expected_output/string.h
new file mode 100644
index 0000000000000..4dcb693c353e4
--- /dev/null
+++ b/libc/newhdrgen/tests/expected_output/string.h
@@ -0,0 +1,102 @@
+//===-- C standard library header string.h --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STRING_H
+#define LLVM_LIBC_STRING_H
+
+#include "__llvm-libc-common.h"
+
+#include "llvm-libc-macros/null-macro.h"
+
+#include <llvm-libc-types/size_t.h>
+
+__BEGIN_C_DECLS
+
+void * memccpy(void *__restrict, const void *__restrict, int, size_t);
+
+void * memchr(const void *, int, size_t);
+
+int memcmp(const void *, const void *, size_t);
+
+void * memcpy(void *__restrict, const void *__restrict, size_t);
+
+void * memmem(const void *, size_t, const void *, size_t);
+
+void * memmove(void *, const void *, size_t);
+
+void * mempcpy(void *__restrict, const void *__restrict, size_t);
+
+void * memrchr(const void *, int, size_t);
+
+void * memset(void *, int, size_t);
+
+void * memset_explicit(void *, int, size_t);
+
+char * stpcpy(char *__restrict, const char *__restrict);
+
+char * stpncpy(char *__restrict, const char *__restrict, size_t);
+
+char * strcasestr(const char *, const char *);
+
+char * strcat(char *__restrict, const char *__restrict);
+
+char * strchr(const char *, int);
+
+char * strchrnul(const char *, int);
+
+int strcmp(const char *, const char *);
+
+int strcoll(const char *, const char *);
+
+char * strcpy(char *__restrict, const char *__restrict);
+
+size_t strcspn(const char *, const char *);
+
+char * strdup(const char *);
+
+char * strerror(int);
+
+char * strerror_r(int, char *, size_t);
+
+size_t strlcat(const char *__restrict, const char *__restrict, size_t);
+
+size_t strlcpy(const char *__restrict, const char *__restrict, size_t);
+
+size_t strlen(const char *);
+
+char * strncat(char *, const char *, size_t);
+
+int strncmp(const char *, const char *, size_t);
+
+char * strncpy(char *__restrict, const char *__restrict, size_t);
+
+char * strndup(const char *, size_t);
+
+size_t strnlen(const char *, size_t);
+
+char * strpbrk(const char *, const char *);
+
+char * strrchr(const char *, int);
+
+char * strsep(char * *__restrict, const char *__restrict);
+
+char * strsignal(int);
+
+size_t strspn(const char *, const char *);
+
+char * strstr(const char *, const char *);
+
+char * strtok(char *__restrict, const char *__restrict);
+
+char * strtok_r(char *__restrict, const char *__restrict, char * *__restrict);
+
+size_t strxfrm(char *__restrict, const char *__restrict, size_t);
+
+__END_C_DECLS
+
+#endif // LLVM_LIBC_STRING_H
diff --git a/libc/newhdrgen/tests/input/string.h.def b/libc/newhdrgen/tests/input/string.h.def
new file mode 100644
index 0000000000000..1bd2687db2bea
--- /dev/null
+++ b/libc/newhdrgen/tests/input/string.h.def
@@ -0,0 +1,18 @@
+//===-- C standard library header string.h --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STRING_H
+#define LLVM_LIBC_STRING_H
+
+#include "__llvm-libc-common.h"
+
+#include "llvm-libc-macros/null-macro.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_STRING_H
diff --git a/libc/newhdrgen/tests/input/test_string.yaml b/libc/newhdrgen/tests/input/test_string.yaml
new file mode 100644
index 0000000000000..2754f856bc807
--- /dev/null
+++ b/libc/newhdrgen/tests/input/test_string.yaml
@@ -0,0 +1,303 @@
+header: string.h
+macros: []
+types:
+ - type_name: size_t
+enums: []
+objects: []
+functions:
+ - name: memcpy
+ standards:
+ - stdc
+ return_type: void *
+ arguments:
+ - type: void *__restrict
+ - type: const void *__restrict
+ - type: size_t
+ - name: memmove
+ standards:
+ - stdc
+ return_type: void *
+ arguments:
+ - type: void *
+ - type: const void *
+ - type: size_t
+ - name: memcmp
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: const void *
+ - type: const void *
+ - type: size_t
+ - name: memchr
+ standards:
+ - stdc
+ return_type: void *
+ arguments:
+ - type: const void *
+ - type: int
+ - type: size_t
+ - name: memset
+ standards:
+ - stdc
+ return_type: void *
+ arguments:
+ - type: void *
+ - type: int
+ - type: size_t
+ - name: memset_explicit
+ standards:
+ - stdc
+ return_type: void *
+ arguments:
+ - type: void *
+ - type: int
+ - type: size_t
+ - name: strcpy
+ standards:
+ - stdc
+ return_type: char
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - name: strncpy
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - type: size_t
+ - name: strcat
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - name: strncat
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: char *
+ - type: const char *
+ - type: size_t
+ - name: strcmp
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strcoll
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strncmp
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - type: size_t
+ - name: strxfrm
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - type: size_t
+ - name: strchr
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: int
+ - name: strcspn
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strdup
+ return_type: char *
+ arguments:
+ - type: const char *
+ - name: strndup
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: size_t
+ - name: strpbrk
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strrchr
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: int
+ - name: strspn
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strstr
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strtok
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - name: strerror
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: int
+ - name: strlen
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: const char *
+ - name: memccpy
+ standards:
+ - POSIX
+ return_type: void *
+ arguments:
+ - type: void *__restrict
+ - type: const void *__restrict
+ - type: int
+ - type: size_t
+ - name: mempcpy
+ standards:
+ - POSIX
+ return_type: void *
+ arguments:
+ - type: void *__restrict
+ - type: const void *__restrict
+ - type: size_t
+ - name: stpcpy
+ standards:
+ - POSIX
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - name: stpncpy
+ standards:
+ - POSIX
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - type: size_t
+ - name: strnlen
+ standards:
+ - POSIX
+ return_type: size_t
+ arguments:
+ - type: const char *
+ - type: size_t
+ - name: strtok_r
+ standards:
+ - POSIX
+ return_type: char *
+ arguments:
+ - type: char *__restrict
+ - type: const char *__restrict
+ - type: char ** __restrict
+ - name: strsignal
+ standards:
+ - POSIX
+ return_type: char *
+ arguments:
+ - type: int
+ - name: memmem
+ standards:
+ - GNUExtensions
+ return_type: void *
+ arguments:
+ - type: const void *
+ - type: size_t
+ - type: const void *
+ - type: size_t
+ - name: memrchr
+ standards:
+ - GNUExtensions
+ return_type: void *
+ arguments:
+ - type: const void *
+ - type: int
+ - type: size_t
+ - name: strerror_r
+ standards:
+ - GNUExtensions
+ return_type: char *
+ arguments:
+ - type: int
+ - type: char *
+ - type: size_t
+ - name: strcasestr
+ standards:
+ - GNUExtensions
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: const char *
+ - name: strchrnul
+ standards:
+ - GNUExtensions
+ return_type: char *
+ arguments:
+ - type: const char *
+ - type: int
+ - name: strlcat
+ standards:
+ - BSDExtensions
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: char *__restrict
+ - type: size_t
+ - name: strlcpy
+ standards:
+ - BSDExtensions
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: char *__restrict
+ - type: size_t
+ - name: strsep
+ standards:
+ - BSDExtensions
+ return_type: char *
+ arguments:
+ - type: char **__restrict
+ - type: char *__restrict
+
diff --git a/libc/newhdrgen/tests/test_integration.py b/libc/newhdrgen/tests/test_integration.py
new file mode 100644
index 0000000000000..ca485dc0377c1
--- /dev/null
+++ b/libc/newhdrgen/tests/test_integration.py
@@ -0,0 +1,42 @@
+import subprocess
+import unittest
+from pathlib import Path
+
+class TestHeaderGenIntegration(unittest.TestCase):
+ def setUp(self):
+ self.output_dir = Path('tests/output')
+ self.maxDiff = None
+
+ def run_script(self, yaml_file, h_def_file, output_dir):
+ result = subprocess.run([
+ 'python3', 'yaml_to_classes.py', yaml_file, h_def_file, '--output_dir', str(output_dir)
+ ], capture_output=True, text=True)
+
+ print("STDOUT:", result.stdout)
+ print("STDERR:", result.stderr)
+ result.check_returncode()
+
+ def compare_files(self, generated_file, expected_file):
+ with generated_file.open('r') as gen_file:
+ gen_content = gen_file.read()
+ with expected_file.open('r') as exp_file:
+ exp_content = exp_file.read()
+
+ self.assertEqual(gen_content, exp_content)
+
+ def test_generate_header(self):
+ # this is for example, will find a way to test everything at once
+ yaml_file = Path('tests/input/test_string.yaml')
+ h_def_file = Path('tests/input/string.h.def')
+ expected_output_file = Path('tests/expected_output/string.h')
+ output_file = self.output_dir / 'string.h'
+
+ if not self.output_dir.exists():
+ self.output_dir.mkdir(parents=True)
+
+ self.run_script(yaml_file, h_def_file, self.output_dir)
+
+ self.compare_files(output_file, expected_output_file)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py
index 9b52c9cf9bb7c..65a990c8a8767 100644
--- a/libc/newhdrgen/yaml_to_classes.py
+++ b/libc/newhdrgen/yaml_to_classes.py
@@ -46,11 +46,13 @@ def yaml_to_classes(yaml_data):
Enumeration(enum_data["name"], enum_data.get("value", None))
)
- for function_data in yaml_data.get("functions", []):
+ functions = yaml_data.get("functions", [])
+ sorted_functions = sorted(functions, key=lambda x: x['name'])
+ for function_data in sorted_functions:
arguments = [arg["type"] for arg in function_data["arguments"]]
guard = function_data.get("guard", None)
attributes = function_data.get("attributes", None)
- standards = (function_data.get("standards", None),)
+ standards = function_data.get("standards", None)
header.add_function(
Function(
function_data["return_type"],
|
You can test this locally with the following command:git-clang-format --diff 03e46475f510d9d7fa813dcfa1fd91894af39862 36332e3562f558af01a4ae1f161da5ec7f8c416e -- libc/newhdrgen/tests/expected_output/test_header.h libc/newhdrgen/tests/output/test_small.h View the diff from clang-format here.diff --git a/libc/newhdrgen/tests/expected_output/test_header.h b/libc/newhdrgen/tests/expected_output/test_header.h
index d6ae0d0e28..be891cdb61 100644
--- a/libc/newhdrgen/tests/expected_output/test_header.h
+++ b/libc/newhdrgen/tests/expected_output/test_header.h
@@ -27,11 +27,11 @@ enum {
__BEGIN_C_DECLS
#ifdef FUNC_A_16
-void func_a()CONST_FUNC_A;
+void func_a() CONST_FUNC_A;
#endif // FUNC_A_16
#ifdef FUNC_B_16
-int func_b(int, float)CONST_FUNC_B;
+int func_b(int, float) CONST_FUNC_B;
#endif // FUNC_B_16
extern obj object_1;
diff --git a/libc/newhdrgen/tests/output/test_small.h b/libc/newhdrgen/tests/output/test_small.h
index d6ae0d0e28..be891cdb61 100644
--- a/libc/newhdrgen/tests/output/test_small.h
+++ b/libc/newhdrgen/tests/output/test_small.h
@@ -27,11 +27,11 @@ enum {
__BEGIN_C_DECLS
#ifdef FUNC_A_16
-void func_a()CONST_FUNC_A;
+void func_a() CONST_FUNC_A;
#endif // FUNC_A_16
#ifdef FUNC_B_16
-int func_b(int, float)CONST_FUNC_B;
+int func_b(int, float) CONST_FUNC_B;
#endif // FUNC_B_16
extern obj object_1;
|
You can test this locally with the following command:darker --check --diff -r 03e46475f510d9d7fa813dcfa1fd91894af39862...36332e3562f558af01a4ae1f161da5ec7f8c416e libc/newhdrgen/tests/test_integration.py libc/newhdrgen/class_implementation/classes/enumeration.py libc/newhdrgen/class_implementation/classes/function.py libc/newhdrgen/class_implementation/classes/object.py libc/newhdrgen/header.py libc/newhdrgen/yaml_to_classes.py View the diff from darker here.--- tests/test_integration.py 2024-07-02 23:49:18.000000 +0000
+++ tests/test_integration.py 2024-07-03 21:32:14.245233 +0000
@@ -17,11 +17,13 @@
output_dir_env = os.getenv("TEST_OUTPUT_DIR")
self.output_dir = Path(
args.output_dir
if args.output_dir
- else output_dir_env if output_dir_env else "libc/newhdrgen/tests/output"
+ else output_dir_env
+ if output_dir_env
+ else "libc/newhdrgen/tests/output"
)
self.maxDiff = None
# Adjust based on your directory structure such as being in build etc.
self.source_dir = Path(__file__).resolve().parent.parent.parent.parent
|
@@ -0,0 +1,303 @@ | |||
header: string.h |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the test, you should make a much smaller yaml file, probably with a different name as well (so it's clear this is just for testing). You also need to make sure you're testing all of the parts, not just functioins. I'd recommend something like this:
header: test_header.h
macros: [MACRO_A, MACRO_B]
types: [type_a, type_b]
enums: [enum_a: [value_1, value_2], enum_b: [value_3]]
objects: [object_1, object_2]
functions: [list of functions]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently it tests the expected output such as string.h from the build directory vs string.h from us. Each line is compared to ensure that the certain macros, enums, objects, etc are there. Does that cover testing all parts?
changed header.py for spacing issues added .strip to script for spacing issues
fixed object class to add ";"
ninja check-hdrgen works
libc/newhdrgen/CMakeLists.txt
Outdated
|
||
set(NEWHDGEN_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests) | ||
|
||
add_test( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add only when in full build mode
Not sure if this is correct but: if(CMAKE_BUILD_TYPE STREQUAL FULL) /..../ endif()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
- created integration tests for libc hdrgen - implemented sorting function names in yaml files through script
Uh oh!
There was an error while loading. Please reload this page.