linux-kselftest-kunit-6.4-rc1
This KUnit update Linux 6.4-rc1 consists of: - several fixes to kunit tool - new klist structure test - support for m68k under QEMU - support for overriding the QEMU serial port - support for SH under QEMU -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAmRFYFsACgkQCwJExA0N Qxw+PxAA1KHnHool3QbzZouFgLgTS2N/hxsOIoWKeUl6guUPX0XYu67FEIyt7p5k a1eFLjt+q4URW/heHKYdffP+Up6xhN5yVP8xJEcbn6GD13lz1clI9RAjObiPOehc KOV90PeAEfzosEGRIp97g4Gzu8NUMZqN7BsKBdzYJ4rEftlcjaILBVp4OfSuCyAi UbYBdRjK4eIOwGXuHVfhNqzH1HRSbzcoSRTywj5qW0Qhpe6KnZBRuZESXYBsxzGb G0nd4+OttjZyplI/xQYwaU0XGAI6roG5G4nAT5YGHLp5g8rTaHetTi+i3iK4iEru wEL0NgywkA0ujAge97RldOjtU97vvSFk7FwxdS9lxaMW/Ut2sN72I2ThI8dBvVRZ fcw8t8mmT1gUv3SCq+s1X13vz22IedXLOfvOY2o/fLk2zxOw5e8FirAz/aFeOf3K ++hK+IQvDmeMMv08bz0ORzdRQcjdwQNQ3klnfdrUVFN9yK+iAllOJ/nrXHLNIXu4 c3ITlAMldcAf2W+LRWzvqqKyT4H8MCXL3L0bBc1M1reRu9nM89AZedO8MHCB0R9Q 2ic0rOxIwZzPJuk0qPDxEVmN7Rpyx85I96YOwRemJTEfdkB/ZX+BfOU0KzinOVHC 3qrHuIw/SyRTlUEDAr53gJ5WHbdjhKAmrd1/FuplyoOSX0w6VVA= =COQn -----END PGP SIGNATURE----- Merge tag 'linux-kselftest-kunit-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest Pull KUnit updates from Shuah Khan: - several fixes to kunit tool - new klist structure test - support for m68k under QEMU - support for overriding the QEMU serial port - support for SH under QEMU * tag 'linux-kselftest-kunit-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: kunit: add tests for using current KUnit test field kunit: tool: Add support for SH under QEMU kunit: tool: Add support for overriding the QEMU serial port .gitignore: Unignore .kunitconfig list: test: Test the klist structure kunit: increase KUNIT_LOG_SIZE to 2048 bytes kunit: Use gfp in kunit_alloc_resource() kernel-doc kunit: tool: fix pre-existing `mypy --strict` errors and update run_checks.py kunit: tool: remove unused imports and variables kunit: tool: add subscripts for type annotations where appropriate kunit: fix bug of extra newline characters in debugfs logs kunit: fix bug in the order of lines in debugfs logs kunit: fix bug in debugfs logs of parameterized tests kunit: tool: Add support for m68k under QEMU
This commit is contained in:
commit
1be89faab3
|
@ -103,6 +103,7 @@ modules.order
|
|||
!.get_maintainer.ignore
|
||||
!.gitattributes
|
||||
!.gitignore
|
||||
!.kunitconfig
|
||||
!.mailmap
|
||||
!.rustfmt.toml
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef void (*kunit_resource_free_t)(struct kunit_resource *);
|
|||
* params.gfp = gfp;
|
||||
*
|
||||
* return kunit_alloc_resource(test, kunit_kmalloc_init,
|
||||
* kunit_kmalloc_free, ¶ms);
|
||||
* kunit_kmalloc_free, gfp, ¶ms);
|
||||
* }
|
||||
*
|
||||
* Resources can also be named, with lookup/removal done on a name
|
||||
|
|
|
@ -34,7 +34,7 @@ DECLARE_STATIC_KEY_FALSE(kunit_running);
|
|||
struct kunit;
|
||||
|
||||
/* Size of log associated with test. */
|
||||
#define KUNIT_LOG_SIZE 512
|
||||
#define KUNIT_LOG_SIZE 2048
|
||||
|
||||
/* Maximum size of parameter description string. */
|
||||
#define KUNIT_PARAM_DESC_SIZE 128
|
||||
|
@ -420,7 +420,7 @@ void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
|
|||
#define kunit_log(lvl, test_or_suite, fmt, ...) \
|
||||
do { \
|
||||
printk(lvl fmt, ##__VA_ARGS__); \
|
||||
kunit_log_append((test_or_suite)->log, fmt "\n", \
|
||||
kunit_log_append((test_or_suite)->log, fmt, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -55,14 +55,24 @@ static int debugfs_print_results(struct seq_file *seq, void *v)
|
|||
enum kunit_status success = kunit_suite_has_succeeded(suite);
|
||||
struct kunit_case *test_case;
|
||||
|
||||
if (!suite || !suite->log)
|
||||
if (!suite)
|
||||
return 0;
|
||||
|
||||
seq_printf(seq, "%s", suite->log);
|
||||
/* Print KTAP header so the debugfs log can be parsed as valid KTAP. */
|
||||
seq_puts(seq, "KTAP version 1\n");
|
||||
seq_puts(seq, "1..1\n");
|
||||
|
||||
/* Print suite header because it is not stored in the test logs. */
|
||||
seq_puts(seq, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
|
||||
seq_printf(seq, KUNIT_SUBTEST_INDENT "# Subtest: %s\n", suite->name);
|
||||
seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
|
||||
|
||||
kunit_suite_for_each_test_case(suite, test_case)
|
||||
debugfs_print_result(seq, suite, test_case);
|
||||
|
||||
if (suite->log)
|
||||
seq_printf(seq, "%s", suite->log);
|
||||
|
||||
seq_printf(seq, "%s %d %s\n",
|
||||
kunit_status_to_ok_not_ok(success), 1, suite->name);
|
||||
return 0;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Author: Brendan Higgins <brendanhiggins@google.com>
|
||||
*/
|
||||
#include <kunit/test.h>
|
||||
#include <kunit/test-bug.h>
|
||||
|
||||
#include "try-catch-impl.h"
|
||||
|
||||
|
@ -443,18 +444,6 @@ static struct kunit_suite kunit_resource_test_suite = {
|
|||
.test_cases = kunit_resource_test_cases,
|
||||
};
|
||||
|
||||
static void kunit_log_test(struct kunit *test);
|
||||
|
||||
static struct kunit_case kunit_log_test_cases[] = {
|
||||
KUNIT_CASE(kunit_log_test),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite kunit_log_test_suite = {
|
||||
.name = "kunit-log-test",
|
||||
.test_cases = kunit_log_test_cases,
|
||||
};
|
||||
|
||||
static void kunit_log_test(struct kunit *test)
|
||||
{
|
||||
struct kunit_suite suite;
|
||||
|
@ -481,6 +470,29 @@ static void kunit_log_test(struct kunit *test)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void kunit_log_newline_test(struct kunit *test)
|
||||
{
|
||||
kunit_info(test, "Add newline\n");
|
||||
if (test->log) {
|
||||
KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(test->log, "Add newline\n"),
|
||||
"Missing log line, full log:\n%s", test->log);
|
||||
KUNIT_EXPECT_NULL(test, strstr(test->log, "Add newline\n\n"));
|
||||
} else {
|
||||
kunit_skip(test, "only useful when debugfs is enabled");
|
||||
}
|
||||
}
|
||||
|
||||
static struct kunit_case kunit_log_test_cases[] = {
|
||||
KUNIT_CASE(kunit_log_test),
|
||||
KUNIT_CASE(kunit_log_newline_test),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite kunit_log_test_suite = {
|
||||
.name = "kunit-log-test",
|
||||
.test_cases = kunit_log_test_cases,
|
||||
};
|
||||
|
||||
static void kunit_status_set_failure_test(struct kunit *test)
|
||||
{
|
||||
struct kunit fake;
|
||||
|
@ -521,7 +533,46 @@ static struct kunit_suite kunit_status_test_suite = {
|
|||
.test_cases = kunit_status_test_cases,
|
||||
};
|
||||
|
||||
static void kunit_current_test(struct kunit *test)
|
||||
{
|
||||
/* Check results of both current->kunit_test and
|
||||
* kunit_get_current_test() are equivalent to current test.
|
||||
*/
|
||||
KUNIT_EXPECT_PTR_EQ(test, test, current->kunit_test);
|
||||
KUNIT_EXPECT_PTR_EQ(test, test, kunit_get_current_test());
|
||||
}
|
||||
|
||||
static void kunit_current_fail_test(struct kunit *test)
|
||||
{
|
||||
struct kunit fake;
|
||||
|
||||
kunit_init_test(&fake, "fake test", NULL);
|
||||
KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS);
|
||||
|
||||
/* Set current->kunit_test to fake test. */
|
||||
current->kunit_test = &fake;
|
||||
|
||||
kunit_fail_current_test("This should make `fake` test fail.");
|
||||
KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE);
|
||||
kunit_cleanup(&fake);
|
||||
|
||||
/* Reset current->kunit_test to current test. */
|
||||
current->kunit_test = test;
|
||||
}
|
||||
|
||||
static struct kunit_case kunit_current_test_cases[] = {
|
||||
KUNIT_CASE(kunit_current_test),
|
||||
KUNIT_CASE(kunit_current_fail_test),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite kunit_current_test_suite = {
|
||||
.name = "kunit_current",
|
||||
.test_cases = kunit_current_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
|
||||
&kunit_log_test_suite, &kunit_status_test_suite);
|
||||
&kunit_log_test_suite, &kunit_status_test_suite,
|
||||
&kunit_current_test_suite);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -108,28 +108,51 @@ static void kunit_print_test_stats(struct kunit *test,
|
|||
stats.total);
|
||||
}
|
||||
|
||||
/**
|
||||
* kunit_log_newline() - Add newline to the end of log if one is not
|
||||
* already present.
|
||||
* @log: The log to add the newline to.
|
||||
*/
|
||||
static void kunit_log_newline(char *log)
|
||||
{
|
||||
int log_len, len_left;
|
||||
|
||||
log_len = strlen(log);
|
||||
len_left = KUNIT_LOG_SIZE - log_len - 1;
|
||||
|
||||
if (log_len > 0 && log[log_len - 1] != '\n')
|
||||
strncat(log, "\n", len_left);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append formatted message to log, size of which is limited to
|
||||
* KUNIT_LOG_SIZE bytes (including null terminating byte).
|
||||
*/
|
||||
void kunit_log_append(char *log, const char *fmt, ...)
|
||||
{
|
||||
char line[KUNIT_LOG_SIZE];
|
||||
va_list args;
|
||||
int len_left;
|
||||
int len, log_len, len_left;
|
||||
|
||||
if (!log)
|
||||
return;
|
||||
|
||||
len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
|
||||
log_len = strlen(log);
|
||||
len_left = KUNIT_LOG_SIZE - log_len - 1;
|
||||
if (len_left <= 0)
|
||||
return;
|
||||
|
||||
/* Evaluate length of line to add to log */
|
||||
va_start(args, fmt);
|
||||
vsnprintf(line, sizeof(line), fmt, args);
|
||||
len = vsnprintf(NULL, 0, fmt, args) + 1;
|
||||
va_end(args);
|
||||
|
||||
strncat(log, line, len_left);
|
||||
/* Print formatted line to the log */
|
||||
va_start(args, fmt);
|
||||
vsnprintf(log + log_len, min(len, len_left), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/* Add newline to end of log if not already present. */
|
||||
kunit_log_newline(log);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_log_append);
|
||||
|
||||
|
@ -147,10 +170,18 @@ EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
|
|||
|
||||
static void kunit_print_suite_start(struct kunit_suite *suite)
|
||||
{
|
||||
kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
|
||||
kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
|
||||
/*
|
||||
* We do not log the test suite header as doing so would
|
||||
* mean debugfs display would consist of the test suite
|
||||
* header prior to individual test results.
|
||||
* Hence directly printk the suite status, and we will
|
||||
* separately seq_printf() the suite header for the debugfs
|
||||
* representation.
|
||||
*/
|
||||
pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
|
||||
pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
|
||||
suite->name);
|
||||
kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
|
||||
pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
|
||||
kunit_suite_num_test_cases(suite));
|
||||
}
|
||||
|
||||
|
@ -167,10 +198,9 @@ static void kunit_print_ok_not_ok(void *test_or_suite,
|
|||
|
||||
/*
|
||||
* We do not log the test suite results as doing so would
|
||||
* mean debugfs display would consist of the test suite
|
||||
* description and status prior to individual test results.
|
||||
* Hence directly printk the suite status, and we will
|
||||
* separately seq_printf() the suite status for the debugfs
|
||||
* mean debugfs display would consist of an incorrect test
|
||||
* number. Hence directly printk the suite result, and we will
|
||||
* separately seq_printf() the suite results for the debugfs
|
||||
* representation.
|
||||
*/
|
||||
if (suite)
|
||||
|
@ -437,7 +467,6 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
|
|||
struct kunit_try_catch_context context;
|
||||
struct kunit_try_catch *try_catch;
|
||||
|
||||
kunit_init_test(test, test_case->name, test_case->log);
|
||||
try_catch = &test->try_catch;
|
||||
|
||||
kunit_try_catch_init(try_catch,
|
||||
|
@ -533,6 +562,8 @@ int kunit_run_tests(struct kunit_suite *suite)
|
|||
struct kunit_result_stats param_stats = { 0 };
|
||||
test_case->status = KUNIT_SKIPPED;
|
||||
|
||||
kunit_init_test(&test, test_case->name, test_case->log);
|
||||
|
||||
if (!test_case->generate_params) {
|
||||
/* Non-parameterised test. */
|
||||
kunit_run_case_catch_errors(suite, test_case, &test);
|
||||
|
|
300
lib/list-test.c
300
lib/list-test.c
|
@ -8,6 +8,7 @@
|
|||
#include <kunit/test.h>
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/klist.h>
|
||||
|
||||
struct list_test_struct {
|
||||
int data;
|
||||
|
@ -1199,6 +1200,303 @@ static struct kunit_suite hlist_test_module = {
|
|||
.test_cases = hlist_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&list_test_module, &hlist_test_module);
|
||||
|
||||
struct klist_test_struct {
|
||||
int data;
|
||||
struct klist klist;
|
||||
struct klist_node klist_node;
|
||||
};
|
||||
|
||||
static int node_count;
|
||||
static struct klist_node *last_node;
|
||||
|
||||
static void check_node(struct klist_node *node_ptr)
|
||||
{
|
||||
node_count++;
|
||||
last_node = node_ptr;
|
||||
}
|
||||
|
||||
static void check_delete_node(struct klist_node *node_ptr)
|
||||
{
|
||||
node_count--;
|
||||
last_node = node_ptr;
|
||||
}
|
||||
|
||||
static void klist_test_add_tail(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, NULL);
|
||||
|
||||
klist_add_tail(&a, &mylist);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 1);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
|
||||
|
||||
klist_add_tail(&b, &mylist);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 2);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
|
||||
|
||||
/* should be [list] -> a -> b */
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
static void klist_test_add_head(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, NULL);
|
||||
|
||||
klist_add_head(&a, &mylist);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 1);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
|
||||
|
||||
klist_add_head(&b, &mylist);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 2);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
|
||||
|
||||
/* should be [list] -> b -> a */
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
static void klist_test_add_behind(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b, c, d;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, NULL);
|
||||
|
||||
klist_add_head(&a, &mylist);
|
||||
klist_add_head(&b, &mylist);
|
||||
|
||||
klist_add_behind(&c, &a);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 3);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
|
||||
|
||||
klist_add_behind(&d, &b);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 4);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
|
||||
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
/* should be [list] -> b -> d -> a -> c*/
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
static void klist_test_add_before(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b, c, d;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, NULL);
|
||||
|
||||
klist_add_head(&a, &mylist);
|
||||
klist_add_head(&b, &mylist);
|
||||
klist_add_before(&c, &a);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 3);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
|
||||
|
||||
klist_add_before(&d, &b);
|
||||
KUNIT_EXPECT_EQ(test, node_count, 4);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
|
||||
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
/* should be [list] -> b -> d -> a -> c*/
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that klist_del() delays the deletion of a node until there
|
||||
* are no other references to it
|
||||
*/
|
||||
static void klist_test_del_refcount_greater_than_zero(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b, c, d;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, &check_delete_node);
|
||||
|
||||
/* Add nodes a,b,c,d to the list*/
|
||||
klist_add_tail(&a, &mylist);
|
||||
klist_add_tail(&b, &mylist);
|
||||
klist_add_tail(&c, &mylist);
|
||||
klist_add_tail(&d, &mylist);
|
||||
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
/* Advance the iterator to point to node c*/
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
|
||||
|
||||
/* Try to delete node c while there is a reference to it*/
|
||||
klist_del(&c);
|
||||
|
||||
/*
|
||||
* Verify that node c is still attached to the list even after being
|
||||
* deleted. Since the iterator still points to c, the reference count is not
|
||||
* decreased to 0
|
||||
*/
|
||||
KUNIT_EXPECT_TRUE(test, klist_node_attached(&c));
|
||||
|
||||
/* Check that node c has not been removed yet*/
|
||||
KUNIT_EXPECT_EQ(test, node_count, 4);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
/*
|
||||
* Since the iterator is no longer pointing to node c, node c is removed
|
||||
* from the list
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, node_count, 3);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that klist_del() deletes a node immediately when there are no
|
||||
* other references to it.
|
||||
*/
|
||||
static void klist_test_del_refcount_zero(struct kunit *test)
|
||||
{
|
||||
struct klist_node a, b, c, d;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, &check_delete_node);
|
||||
|
||||
/* Add nodes a,b,c,d to the list*/
|
||||
klist_add_tail(&a, &mylist);
|
||||
klist_add_tail(&b, &mylist);
|
||||
klist_add_tail(&c, &mylist);
|
||||
klist_add_tail(&d, &mylist);
|
||||
/* Delete node c*/
|
||||
klist_del(&c);
|
||||
|
||||
/* Check that node c is deleted from the list*/
|
||||
KUNIT_EXPECT_EQ(test, node_count, 3);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
|
||||
|
||||
/* Should be [list] -> a -> b -> d*/
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
static void klist_test_remove(struct kunit *test)
|
||||
{
|
||||
/* This test doesn't check correctness under concurrent access */
|
||||
struct klist_node a, b, c, d;
|
||||
struct klist mylist;
|
||||
struct klist_iter i;
|
||||
|
||||
node_count = 0;
|
||||
klist_init(&mylist, &check_node, &check_delete_node);
|
||||
|
||||
/* Add nodes a,b,c,d to the list*/
|
||||
klist_add_tail(&a, &mylist);
|
||||
klist_add_tail(&b, &mylist);
|
||||
klist_add_tail(&c, &mylist);
|
||||
klist_add_tail(&d, &mylist);
|
||||
/* Delete node c*/
|
||||
klist_remove(&c);
|
||||
|
||||
/* Check the nodes in the list*/
|
||||
KUNIT_EXPECT_EQ(test, node_count, 3);
|
||||
KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
|
||||
|
||||
/* should be [list] -> a -> b -> d*/
|
||||
klist_iter_init(&mylist, &i);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
|
||||
KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
|
||||
KUNIT_EXPECT_NULL(test, klist_next(&i));
|
||||
|
||||
klist_iter_exit(&i);
|
||||
|
||||
}
|
||||
|
||||
static void klist_test_node_attached(struct kunit *test)
|
||||
{
|
||||
struct klist_node a = {};
|
||||
struct klist mylist;
|
||||
|
||||
klist_init(&mylist, NULL, NULL);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
|
||||
klist_add_head(&a, &mylist);
|
||||
KUNIT_EXPECT_TRUE(test, klist_node_attached(&a));
|
||||
klist_del(&a);
|
||||
KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
|
||||
|
||||
}
|
||||
|
||||
static struct kunit_case klist_test_cases[] = {
|
||||
KUNIT_CASE(klist_test_add_tail),
|
||||
KUNIT_CASE(klist_test_add_head),
|
||||
KUNIT_CASE(klist_test_add_behind),
|
||||
KUNIT_CASE(klist_test_add_before),
|
||||
KUNIT_CASE(klist_test_del_refcount_greater_than_zero),
|
||||
KUNIT_CASE(klist_test_del_refcount_zero),
|
||||
KUNIT_CASE(klist_test_remove),
|
||||
KUNIT_CASE(klist_test_node_attached),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite klist_test_module = {
|
||||
.name = "klist",
|
||||
.test_cases = klist_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&list_test_module, &hlist_test_module, &klist_test_module);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -123,7 +123,7 @@ def _suites_from_test_list(tests: List[str]) -> List[str]:
|
|||
parts = t.split('.', maxsplit=2)
|
||||
if len(parts) != 2:
|
||||
raise ValueError(f'internal KUnit error, test name should be of the form "<suite>.<test>", got "{t}"')
|
||||
suite, case = parts
|
||||
suite, _ = parts
|
||||
if not suites or suites[-1] != suite:
|
||||
suites.append(suite)
|
||||
return suites
|
||||
|
@ -269,7 +269,7 @@ def massage_argv(argv: Sequence[str]) -> Sequence[str]:
|
|||
def get_default_jobs() -> int:
|
||||
return len(os.sched_getaffinity(0))
|
||||
|
||||
def add_common_opts(parser) -> None:
|
||||
def add_common_opts(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument('--build_dir',
|
||||
help='As in the make command, it specifies the build '
|
||||
'directory.',
|
||||
|
@ -320,13 +320,13 @@ def add_common_opts(parser) -> None:
|
|||
help='Additional QEMU arguments, e.g. "-smp 8"',
|
||||
action='append', metavar='')
|
||||
|
||||
def add_build_opts(parser) -> None:
|
||||
def add_build_opts(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument('--jobs',
|
||||
help='As in the make command, "Specifies the number of '
|
||||
'jobs (commands) to run simultaneously."',
|
||||
type=int, default=get_default_jobs(), metavar='N')
|
||||
|
||||
def add_exec_opts(parser) -> None:
|
||||
def add_exec_opts(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument('--timeout',
|
||||
help='maximum number of seconds to allow for all tests '
|
||||
'to run. This does not include time taken to build the '
|
||||
|
@ -351,7 +351,7 @@ def add_exec_opts(parser) -> None:
|
|||
type=str,
|
||||
choices=['suite', 'test'])
|
||||
|
||||
def add_parse_opts(parser) -> None:
|
||||
def add_parse_opts(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument('--raw_output', help='If set don\'t parse output from kernel. '
|
||||
'By default, filters to just KUnit output. Use '
|
||||
'--raw_output=all to show everything',
|
||||
|
@ -386,7 +386,7 @@ def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree
|
|||
extra_qemu_args=qemu_args)
|
||||
|
||||
|
||||
def run_handler(cli_args):
|
||||
def run_handler(cli_args: argparse.Namespace) -> None:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
|
@ -405,7 +405,7 @@ def run_handler(cli_args):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def config_handler(cli_args):
|
||||
def config_handler(cli_args: argparse.Namespace) -> None:
|
||||
if cli_args.build_dir and (
|
||||
not os.path.exists(cli_args.build_dir)):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
@ -421,7 +421,7 @@ def config_handler(cli_args):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def build_handler(cli_args):
|
||||
def build_handler(cli_args: argparse.Namespace) -> None:
|
||||
linux = tree_from_args(cli_args)
|
||||
request = KunitBuildRequest(build_dir=cli_args.build_dir,
|
||||
make_options=cli_args.make_options,
|
||||
|
@ -434,7 +434,7 @@ def build_handler(cli_args):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def exec_handler(cli_args):
|
||||
def exec_handler(cli_args: argparse.Namespace) -> None:
|
||||
linux = tree_from_args(cli_args)
|
||||
exec_request = KunitExecRequest(raw_output=cli_args.raw_output,
|
||||
build_dir=cli_args.build_dir,
|
||||
|
@ -450,10 +450,10 @@ def exec_handler(cli_args):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_handler(cli_args):
|
||||
def parse_handler(cli_args: argparse.Namespace) -> None:
|
||||
if cli_args.file is None:
|
||||
sys.stdin.reconfigure(errors='backslashreplace') # pytype: disable=attribute-error
|
||||
kunit_output = sys.stdin
|
||||
sys.stdin.reconfigure(errors='backslashreplace') # type: ignore
|
||||
kunit_output = sys.stdin # type: Iterable[str]
|
||||
else:
|
||||
with open(cli_args.file, 'r', errors='backslashreplace') as f:
|
||||
kunit_output = f.read().splitlines()
|
||||
|
@ -475,7 +475,7 @@ subcommand_handlers_map = {
|
|||
}
|
||||
|
||||
|
||||
def main(argv):
|
||||
def main(argv: Sequence[str]) -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Helps writing and running KUnit tests.')
|
||||
subparser = parser.add_subparsers(dest='subcommand')
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
from dataclasses import dataclass
|
||||
import re
|
||||
from typing import Dict, Iterable, List, Set, Tuple
|
||||
from typing import Any, Dict, Iterable, List, Tuple
|
||||
|
||||
CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$'
|
||||
CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
|
||||
|
@ -34,7 +34,7 @@ class Kconfig:
|
|||
def __init__(self) -> None:
|
||||
self._entries = {} # type: Dict[str, str]
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
return self._entries == other._entries
|
||||
|
|
|
@ -16,9 +16,9 @@ import shutil
|
|||
import signal
|
||||
import threading
|
||||
from typing import Iterator, List, Optional, Tuple
|
||||
from types import FrameType
|
||||
|
||||
import kunit_config
|
||||
from kunit_printer import stdout
|
||||
import qemu_config
|
||||
|
||||
KCONFIG_PATH = '.config'
|
||||
|
@ -57,7 +57,7 @@ class LinuxSourceTreeOperations:
|
|||
def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
|
||||
return base_kunitconfig
|
||||
|
||||
def make_olddefconfig(self, build_dir: str, make_options) -> None:
|
||||
def make_olddefconfig(self, build_dir: str, make_options: Optional[List[str]]) -> None:
|
||||
command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, 'olddefconfig']
|
||||
if self._cross_compile:
|
||||
command += ['CROSS_COMPILE=' + self._cross_compile]
|
||||
|
@ -71,7 +71,7 @@ class LinuxSourceTreeOperations:
|
|||
except subprocess.CalledProcessError as e:
|
||||
raise ConfigError(e.output.decode())
|
||||
|
||||
def make(self, jobs, build_dir: str, make_options) -> None:
|
||||
def make(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> None:
|
||||
command = ['make', 'ARCH=' + self._linux_arch, 'O=' + build_dir, '--jobs=' + str(jobs)]
|
||||
if make_options:
|
||||
command.extend(make_options)
|
||||
|
@ -92,7 +92,7 @@ class LinuxSourceTreeOperations:
|
|||
if stderr: # likely only due to build warnings
|
||||
print(stderr.decode())
|
||||
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
|
||||
raise RuntimeError('not implemented!')
|
||||
|
||||
|
||||
|
@ -106,13 +106,14 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
|
|||
self._kernel_path = qemu_arch_params.kernel_path
|
||||
self._kernel_command_line = qemu_arch_params.kernel_command_line + ' kunit_shutdown=reboot'
|
||||
self._extra_qemu_params = qemu_arch_params.extra_qemu_params
|
||||
self._serial = qemu_arch_params.serial
|
||||
|
||||
def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
|
||||
kconfig = kunit_config.parse_from_string(self._kconfig)
|
||||
kconfig.merge_in_entries(base_kunitconfig)
|
||||
return kconfig
|
||||
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
|
||||
kernel_path = os.path.join(build_dir, self._kernel_path)
|
||||
qemu_command = ['qemu-system-' + self._qemu_arch,
|
||||
'-nodefaults',
|
||||
|
@ -121,7 +122,7 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
|
|||
'-append', ' '.join(params + [self._kernel_command_line]),
|
||||
'-no-reboot',
|
||||
'-nographic',
|
||||
'-serial', 'stdio'] + self._extra_qemu_params
|
||||
'-serial', self._serial] + self._extra_qemu_params
|
||||
# Note: shlex.join() does what we want, but requires python 3.8+.
|
||||
print('Running tests with:\n$', ' '.join(shlex.quote(arg) for arg in qemu_command))
|
||||
return subprocess.Popen(qemu_command,
|
||||
|
@ -133,7 +134,7 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations):
|
|||
class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations):
|
||||
"""An abstraction over command line operations performed on a source tree."""
|
||||
|
||||
def __init__(self, cross_compile=None):
|
||||
def __init__(self, cross_compile: Optional[str]=None):
|
||||
super().__init__(linux_arch='um', cross_compile=cross_compile)
|
||||
|
||||
def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig:
|
||||
|
@ -141,7 +142,7 @@ class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations):
|
|||
kconfig.merge_in_entries(base_kunitconfig)
|
||||
return kconfig
|
||||
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen:
|
||||
def start(self, params: List[str], build_dir: str) -> subprocess.Popen[str]:
|
||||
"""Runs the Linux UML binary. Must be named 'linux'."""
|
||||
linux_bin = os.path.join(build_dir, 'linux')
|
||||
params.extend(['mem=1G', 'console=tty', 'kunit_shutdown=halt'])
|
||||
|
@ -216,7 +217,7 @@ def _get_qemu_ops(config_path: str,
|
|||
|
||||
if not hasattr(config, 'QEMU_ARCH'):
|
||||
raise ValueError('qemu_config module missing "QEMU_ARCH": ' + config_path)
|
||||
params: qemu_config.QemuArchParams = config.QEMU_ARCH # type: ignore
|
||||
params: qemu_config.QemuArchParams = config.QEMU_ARCH
|
||||
if extra_qemu_args:
|
||||
params.extra_qemu_params.extend(extra_qemu_args)
|
||||
return params.linux_arch, LinuxSourceTreeOperationsQemu(
|
||||
|
@ -230,10 +231,10 @@ class LinuxSourceTree:
|
|||
build_dir: str,
|
||||
kunitconfig_paths: Optional[List[str]]=None,
|
||||
kconfig_add: Optional[List[str]]=None,
|
||||
arch=None,
|
||||
cross_compile=None,
|
||||
qemu_config_path=None,
|
||||
extra_qemu_args=None) -> None:
|
||||
arch: Optional[str]=None,
|
||||
cross_compile: Optional[str]=None,
|
||||
qemu_config_path: Optional[str]=None,
|
||||
extra_qemu_args: Optional[List[str]]=None) -> None:
|
||||
signal.signal(signal.SIGINT, self.signal_handler)
|
||||
if qemu_config_path:
|
||||
self._arch, self._ops = _get_qemu_ops(qemu_config_path, extra_qemu_args, cross_compile)
|
||||
|
@ -276,7 +277,7 @@ class LinuxSourceTree:
|
|||
logging.error(message)
|
||||
return False
|
||||
|
||||
def build_config(self, build_dir: str, make_options) -> bool:
|
||||
def build_config(self, build_dir: str, make_options: Optional[List[str]]) -> bool:
|
||||
kconfig_path = get_kconfig_path(build_dir)
|
||||
if build_dir and not os.path.exists(build_dir):
|
||||
os.mkdir(build_dir)
|
||||
|
@ -304,7 +305,7 @@ class LinuxSourceTree:
|
|||
old_kconfig = kunit_config.parse_file(old_path)
|
||||
return old_kconfig != self._kconfig
|
||||
|
||||
def build_reconfig(self, build_dir: str, make_options) -> bool:
|
||||
def build_reconfig(self, build_dir: str, make_options: Optional[List[str]]) -> bool:
|
||||
"""Creates a new .config if it is not a subset of the .kunitconfig."""
|
||||
kconfig_path = get_kconfig_path(build_dir)
|
||||
if not os.path.exists(kconfig_path):
|
||||
|
@ -320,7 +321,7 @@ class LinuxSourceTree:
|
|||
os.remove(kconfig_path)
|
||||
return self.build_config(build_dir, make_options)
|
||||
|
||||
def build_kernel(self, jobs, build_dir: str, make_options) -> bool:
|
||||
def build_kernel(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> bool:
|
||||
try:
|
||||
self._ops.make_olddefconfig(build_dir, make_options)
|
||||
self._ops.make(jobs, build_dir, make_options)
|
||||
|
@ -329,7 +330,7 @@ class LinuxSourceTree:
|
|||
return False
|
||||
return self.validate_config(build_dir)
|
||||
|
||||
def run_kernel(self, args=None, build_dir='', filter_glob='', timeout=None) -> Iterator[str]:
|
||||
def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', timeout: Optional[int]=None) -> Iterator[str]:
|
||||
if not args:
|
||||
args = []
|
||||
if filter_glob:
|
||||
|
@ -340,7 +341,7 @@ class LinuxSourceTree:
|
|||
assert process.stdout is not None # tell mypy it's set
|
||||
|
||||
# Enforce the timeout in a background thread.
|
||||
def _wait_proc():
|
||||
def _wait_proc() -> None:
|
||||
try:
|
||||
process.wait(timeout=timeout)
|
||||
except Exception as e:
|
||||
|
@ -366,6 +367,6 @@ class LinuxSourceTree:
|
|||
waiter.join()
|
||||
subprocess.call(['stty', 'sane'])
|
||||
|
||||
def signal_handler(self, unused_sig, unused_frame) -> None:
|
||||
def signal_handler(self, unused_sig: int, unused_frame: Optional[FrameType]) -> None:
|
||||
logging.error('Build interruption occurred. Cleaning console.')
|
||||
subprocess.call(['stty', 'sane'])
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
from enum import Enum, auto
|
||||
|
|
|
@ -15,7 +15,7 @@ _RESET = '\033[0;0m'
|
|||
class Printer:
|
||||
"""Wraps a file object, providing utilities for coloring output, etc."""
|
||||
|
||||
def __init__(self, output: typing.IO):
|
||||
def __init__(self, output: typing.IO[str]):
|
||||
self._output = output
|
||||
self._use_color = output.isatty()
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ class KUnitParserTest(unittest.TestCase):
|
|||
def test_parse_subtest_header(self):
|
||||
ktap_log = test_data_path('test_parse_subtest_header.log')
|
||||
with open(ktap_log) as file:
|
||||
result = kunit_parser.parse_run_tests(file.readlines())
|
||||
kunit_parser.parse_run_tests(file.readlines())
|
||||
self.print_mock.assert_any_call(StrContains('suite (1 subtest)'))
|
||||
|
||||
def test_show_test_output_on_failure(self):
|
||||
|
|
|
@ -17,3 +17,4 @@ class QemuArchParams:
|
|||
kernel_path: str
|
||||
kernel_command_line: str
|
||||
extra_qemu_params: List[str]
|
||||
serial: str = 'stdio'
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
from ..qemu_config import QemuArchParams
|
||||
|
||||
QEMU_ARCH = QemuArchParams(linux_arch='m68k',
|
||||
kconfig='''
|
||||
CONFIG_VIRT=y''',
|
||||
qemu_arch='m68k',
|
||||
kernel_path='vmlinux',
|
||||
kernel_command_line='console=hvc0',
|
||||
extra_qemu_params=['-machine', 'virt'])
|
|
@ -0,0 +1,17 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
from ..qemu_config import QemuArchParams
|
||||
|
||||
QEMU_ARCH = QemuArchParams(linux_arch='sh',
|
||||
kconfig='''
|
||||
CONFIG_CPU_SUBTYPE_SH7751R=y
|
||||
CONFIG_MEMORY_START=0x0c000000
|
||||
CONFIG_SH_RTS7751R2D=y
|
||||
CONFIG_RTS7751R2D_PLUS=y
|
||||
CONFIG_SERIAL_SH_SCI=y''',
|
||||
qemu_arch='sh4',
|
||||
kernel_path='arch/sh/boot/zImage',
|
||||
kernel_command_line='console=ttySC1',
|
||||
serial='null',
|
||||
extra_qemu_params=[
|
||||
'-machine', 'r2d',
|
||||
'-serial', 'mon:stdio'])
|
|
@ -23,7 +23,7 @@ commands: Dict[str, Sequence[str]] = {
|
|||
'kunit_tool_test.py': ['./kunit_tool_test.py'],
|
||||
'kunit smoke test': ['./kunit.py', 'run', '--kunitconfig=lib/kunit', '--build_dir=kunit_run_checks'],
|
||||
'pytype': ['/bin/sh', '-c', 'pytype *.py'],
|
||||
'mypy': ['/bin/sh', '-c', 'mypy *.py'],
|
||||
'mypy': ['mypy', '--strict', '--exclude', '_test.py$', '--exclude', 'qemu_configs/', '.'],
|
||||
}
|
||||
|
||||
# The user might not have mypy or pytype installed, skip them if so.
|
||||
|
@ -37,7 +37,7 @@ def main(argv: Sequence[str]) -> None:
|
|||
if argv:
|
||||
raise RuntimeError('This script takes no arguments')
|
||||
|
||||
future_to_name: Dict[futures.Future, str] = {}
|
||||
future_to_name: Dict[futures.Future[None], str] = {}
|
||||
executor = futures.ThreadPoolExecutor(max_workers=len(commands))
|
||||
for name, argv in commands.items():
|
||||
if name in necessary_deps and shutil.which(necessary_deps[name]) is None:
|
||||
|
@ -73,7 +73,7 @@ def main(argv: Sequence[str]) -> None:
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def run_cmd(argv: Sequence[str]):
|
||||
def run_cmd(argv: Sequence[str]) -> None:
|
||||
subprocess.check_output(argv, stderr=subprocess.STDOUT, cwd=ABS_TOOL_PATH, timeout=TIMEOUT)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue