kcl-lang / kcl

KCL Programming Language (CNCF Sandbox Project). https://kcl-lang.io
https://kcl-lang.io
Apache License 2.0
1.62k stars 113 forks source link

[Design] KCL support user behavior test and test tool user interface and workflow #178

Closed amyXia1994 closed 8 months ago

amyXia1994 commented 2 years ago

Feature Request about the KCL test tool

Describe the feature you'd like:

Enhanced KCL test framework and tools to improve the code quality and stability, and help developers of the kcl repo or library gain more confidence after modifying their KCL code for example in the module repo: https://github.com/kcl-lang/modules.

The community basically divides "configuration validation and testing" into several phases:

Basic lib developers and end users are distinguished in terms of scenarios of configuration test:

ref: https://sre.google/workbook/configuration-specifics/

With the help of KCL language tools, the configuration verification in the local development - integration - end to end process is connected.

The verification and test of KCL code can be divided into three phases: local development, continuous integration, and end-to-end verification:

Describe alternatives you've considered:

Provide kcl test command-line tool, integrate shortcut entry in KCL IDE. Integrate to internal/external CICD pipeline and Git hook.

Features about enhanced kcl test tool

Feature | Scenario(what it solves) | milestone -- | -- | -- basic test capacity | Trigger tests with cli under specific directory, and during the execution output the real-time logging, and produce a summary of all the test cases; support the following test coding interface, including the given-when-then pattern, some helper function to improve readability |   tools and ecology engagement | tools: embed the kcl deps tools to support partial testing; support quick entrance in popular ide platform; support popular protocol and specs about test coverage and test report; embedded in github/gitlab action |   skipped test & specify which case to test | uses can input matching regex to execute specific tests when triggered by cli; Users can test a single case when triggered in IDE; the CI pipeline can trigger specific test cases according the kusion deps result |   coverage | after landing in the kcl repository, a test coverage threshold can be set to improve the code quality and ensure that the import models/schemas/attributes are under test. | support step by step: 1. first support test coverage on schema level and then detail to schema attribute level; 2. branch coverage and line coverage require the capacity of core KCL runtime. test report | support test report specs such as xUnit, and engage to existing CICD tools to run quantitative analysis and visual presentation |   multi-input of one test case | Improve test code reuse |   mock | Two typical scenarios:1. kcl plugin enables access to external systems such as app meta center, cmdb, and those part of code should be mocked in ut. 2. the project_context plugin will check the directory of the entrance files and read the file content of project.yaml/stack.yaml, and that plugin is widely used in nearly all of the basic libs in konfig repo, and limits the flexibility to test basic libs since the files under test must be under a standard stack structure | the necessity and priority to be decided by users requirement benchmark | The performance of the configuration code is quantifiable and can be used as input when other platforms wants to integrate | to be decided by users of both platform users and fuzzing | can be used to test error-prone and complex logics and functions |   performance | parallel execution of test cases | first support pseudo concurrent, that is to say, just concurrently call the compile API concurrently single-step debug |   | ### Test code interface design Test suite definition: Lambda function literal variable starting with `test_` located in the `*_test.k` file. #### Code Test Example 1 + main.k ```python jsonpatch: (any, str) -> any = lambda ... # Omit the result ``` + main_test.k ``` python test_custom_log_volume_test = lambda { data = { a = [1, 2, 3] } assert jsonpatch(data, "a/0", 2).a[0] == 2, "2", "error message" } ``` ### Semantic level enhancement of kcl deps tool The kcl deps tool need to be enhanced at the semantic level to identify which stacks have dependencies on a given basic schema/attribute - Before execution of ```kcl test``` command, users need to know the scope to test, and that will be the input to specify the test cases. - After modifying the logic in basic libs, lib developers need to know the impact on the downstream stacks: which stacks are affected, and the what changes happened to the final configuration data of those affected stacks, so that they can decide if the basic lib change could be released. ## User Interface and Workflow ```shell kcl test [OPTIONS] [TESTNAME] ``` + TESTNAME: If specified, only run tests containing this string in their names ```shell kcl test # test the current package kcl test test_jsonpatch # run tests containing this string in their names ``` ## Impl Interface + TestRunner ```rust pub struct TestResult { pub errors: Vec, } trait TestRunner { type Suite; fn look_up_test_suites>(work_dir: P, package: &str) -> &[Self::Suite]; fn run(suites: &[Self::Suite]) -> Result<[TestResult]>; } ``` + Reporter ```rust trait TestReporter { fn report(suite: &TestResult, w: Writer) -> Result<()>; } ``` ## Teachability, Documentation, Adoption, Migration Strategy Migration Strategy: 1. add test code on basic libs: https://github.com/kcl-lang/artifacthub 2. support kcl test in local and CI stages ## Reference - google sre workbook - Configuration Specifics: https://sre.google/workbook/configuration-specifics/ - terraform test design: https://www.terraform.io/language/modules/testing-experiment - terraform testing: https://www.hashicorp.com/blog/testing-hashicorp-terraform - best practice on Terraform code from Azure: https://docs.microsoft.com/en-us/azure/developer/terraform/best-practices-testing-overview - terraform compliance: https://terraform-compliance.com/ - terratest: https://terratest.gruntwork.io/ - jsonnet test: https://dev.to/cuotos/unit-testing-complex-jsonnet-objects-and-arrays-kpe - opa test: https://www.openpolicyagent.org/docs/latest/policy-testing/ - cuelang test: https://github.com/KurtRudolph/cuelang-testing
amyXia1994 commented 2 years ago
  • provide test API: Test(testFunc TestFunc, inputs []TestCase, options TestOptions) -> []TestResult
  • support sample test(only a representative subset of testcases will be tested) to save local developing time
amyXia1994 commented 2 years ago

from shupeng:

  • app level compliance test: end users like app owners need to track the backend output and to check if the backend data meet the constraint in app's level. They've developed some postscripts to do those validations. It's better to be included in KCL unit test. for example, may look like this:
import testing
testing.backend_result.when(lambda item {item.kind == "Service"}).then(lambda ip {ip == "some valid ip"})
  • for unit tests on basic libs: treating all of the stacks as test cases can make basic lib developer feel safer before release, so it's meaningful and can be kept as it is for now. In the future, if basic lib testing causes too much time and has a significant efficiency effect, the concept of basic lib version management can be introduced to konfig repo. From the perspective of software development, involve version and releasing management to basic lib development. For example, one week or one day as a developing iteration and only trigger full stack test in each iteration.
Peefy commented 2 years ago

Debugging capability and test coverage require a separate debugging toolchain and KCL Runtime support, and separate issues can be tracked and linked here.

amyXia1994 commented 2 years ago

design on end-to-end testing

konfig's CI pipeline can integrate Terratest to perform end to end testing.

Terratest has developed a bundle of go SDK with some helper functions and patterns to provide end-to-end test for popular runtime including terraform, k8s, packer, AWS, Azure, Google CloudPlatform, OpenPolicyAgent, docker.

The thought of terratest is mainly about using popular GPL like go, perform a set of "apply-validate-destroy" operation based on calling k8s/terraform/.. runtime API to check if a single application work in the real world or, multiple applications work together. And for checking if the application work as expected, it uses HTTP calls, accessing the cloud services' API, or other ways to connect to the service according to the runtime entity it bases on.