kcl-lang.io/kpm@v0.8.7-0.20240520061008-9fc4c5efc8c7/test/e2e/kpm_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/onsi/ginkgo/v2"
    11  	"github.com/onsi/gomega"
    12  	v1 "github.com/opencontainers/image-spec/specs-go/v1"
    13  	"kcl-lang.io/kpm/pkg/client"
    14  	"kcl-lang.io/kpm/pkg/constants"
    15  	"kcl-lang.io/kpm/pkg/opt"
    16  	"kcl-lang.io/kpm/pkg/utils"
    17  	"oras.land/oras-go/v2"
    18  	"oras.land/oras-go/v2/registry/remote"
    19  	"oras.land/oras-go/v2/registry/remote/auth"
    20  	"oras.land/oras-go/v2/registry/remote/retry"
    21  )
    22  
    23  var _ = ginkgo.Describe("Kpm CLI Testing", func() {
    24  	ginkgo.Context("testing 'exec kpm outside a kcl package'", func() {
    25  		testSuites := LoadAllTestSuites(filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "exec_outside_pkg"))
    26  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
    27  
    28  		for _, ts := range testSuites {
    29  			// In the for loop, the variable ts is defined outside the scope of the ginkgo.It function.
    30  			// This means that when the ginkgo.It function is executed,
    31  			// it will always use the value of ts from the last iteration of the for loop.
    32  			// To fix this issue, create a new variable inside the loop with the same value as ts,
    33  			// and use that variable inside the ginkgo.It function.
    34  			ts := ts
    35  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
    36  				workspace := GetWorkspace()
    37  				Copy(filepath.Join(testDataRoot, "kcl1.tar"), filepath.Join(workspace, "kcl1.tar"))
    38  				Copy(filepath.Join(testDataRoot, "exist_but_not_tar"), filepath.Join(workspace, "exist_but_not_tar"))
    39  
    40  				stdout, stderr, err := ExecKpmWithWorkDir(ts.Input, workspace)
    41  
    42  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
    43  
    44  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
    45  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
    46  
    47  				// Using regular expressions may miss some cases where the string is empty.
    48  				//
    49  				// Since the login/logout-related test cases will output time information,
    50  				// they cannot be compared with method 'Equal',
    51  				// so 'ContainSubstring' is used to compare the results.
    52  				gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
    53  				gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
    54  			})
    55  		}
    56  	})
    57  
    58  	ginkgo.Context("testing 'exec kpm inside a kcl package'", func() {
    59  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "exec_inside_pkg")
    60  		testSuites := LoadAllTestSuites(testSuitesRoot)
    61  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
    62  		for _, ts := range testSuites {
    63  			ts := ts
    64  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
    65  				workspace := GetWorkspace()
    66  
    67  				CopyDir(filepath.Join(testDataRoot, "test_kcl"), filepath.Join(workspace, "test_kcl"))
    68  				CopyDir(filepath.Join(testDataRoot, "a_kcl_pkg_dep_one_pkg"), filepath.Join(workspace, "a_kcl_pkg_dep_one_pkg"))
    69  				CopyDir(filepath.Join(testDataRoot, "a_kcl_pkg_dep_one_pkg_2"), filepath.Join(workspace, "a_kcl_pkg_dep_one_pkg_2"))
    70  				CopyDir(filepath.Join(testDataRoot, "a_kcl_pkg_dep_one_pkg_3"), filepath.Join(workspace, "a_kcl_pkg_dep_one_pkg_3"))
    71  				CopyDir(filepath.Join(testDataRoot, "a_kcl_pkg_dep_one_pkg_4"), filepath.Join(workspace, "a_kcl_pkg_dep_one_pkg_4"))
    72  				CopyDir(filepath.Join(testDataRoot, "a_kcl_pkg_dep_one_pkg_5"), filepath.Join(workspace, "a_kcl_pkg_dep_one_pkg_5"))
    73  				CopyDir(filepath.Join(testDataRoot, "an_invalid_kcl_pkg"), filepath.Join(workspace, "an_invalid_kcl_pkg"))
    74  
    75  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", workspace)
    76  
    77  				stdout, stderr, err := ExecKpmWithWorkDir(input, filepath.Join(workspace, "test_kcl"))
    78  
    79  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
    80  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
    81  
    82  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
    83  				if strings.Contains(ts.ExpectStdout, "<un_ordered>") {
    84  					expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<un_ordered>", "")
    85  					gomega.Expect(RemoveLineOrder(stdout)).To(gomega.ContainSubstring(RemoveLineOrder(expectedStdout)))
    86  				} else if strings.Contains(ts.ExpectStderr, "<un_ordered>") {
    87  					expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<un_ordered>", "")
    88  					gomega.Expect(RemoveLineOrder(stderr)).To(gomega.ContainSubstring(RemoveLineOrder(expectedStderr)))
    89  				} else {
    90  					gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
    91  					gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
    92  				}
    93  			})
    94  		}
    95  	})
    96  
    97  	ginkgo.Context("testing kpm workflows", func() {
    98  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "workflows")
    99  
   100  		files, _ := os.ReadDir(testSuitesRoot)
   101  		for _, f := range files {
   102  			file := f
   103  			ginkgo.It(filepath.Join(testSuitesRoot, file.Name()), func() {
   104  				if file.IsDir() {
   105  					testSuites := LoadAllTestSuites(filepath.Join(testSuitesRoot, file.Name()))
   106  					for _, ts := range testSuites {
   107  						ts := ts
   108  						workspace := GetWorkspace()
   109  
   110  						stdout, stderr, err := ExecKpmWithWorkDir(ts.Input, workspace)
   111  
   112  						expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   113  						expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   114  
   115  						gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   116  						if !IsIgnore(expectedStdout) {
   117  							gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   118  						}
   119  						if !IsIgnore(expectedStderr) {
   120  							gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   121  						}
   122  					}
   123  				}
   124  			})
   125  		}
   126  	})
   127  
   128  	ginkgo.Context("testing 'kpm run '", func() {
   129  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "kpm_run")
   130  		testSuites := LoadAllTestSuites(testSuitesRoot)
   131  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
   132  		for _, ts := range testSuites {
   133  			ts := ts
   134  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
   135  				workspace := GetWorkspace()
   136  
   137  				testSuitePath := filepath.Join(testDataRoot, ts.Name)
   138  				testWorkspace := workspace
   139  				if exist, _ := utils.Exists(testSuitePath); exist {
   140  					CopyDir(testSuitePath, filepath.Join(workspace, ts.Name))
   141  					testWorkspace = filepath.Join(workspace, ts.Name)
   142  				}
   143  
   144  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", testWorkspace)
   145  				stdout, stderr, err := ExecKpmWithWorkDir(input, testWorkspace)
   146  
   147  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   148  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   149  
   150  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   151  				gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   152  				gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   153  			})
   154  		}
   155  	})
   156  
   157  	ginkgo.Context("testing 'kpm update '", func() {
   158  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "kpm_update")
   159  		testSuites := LoadAllTestSuites(testSuitesRoot)
   160  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
   161  		for _, ts := range testSuites {
   162  			ts := ts
   163  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
   164  				workspace := GetWorkspace()
   165  				CopyDir(filepath.Join(testDataRoot, ts.Name), filepath.Join(workspace, ts.Name))
   166  
   167  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", filepath.Join(workspace, ts.Name))
   168  				stdout, stderr, err := ExecKpmWithWorkDir(input, filepath.Join(workspace, ts.Name, "test_update"))
   169  
   170  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   171  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   172  
   173  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   174  				gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   175  				gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   176  			})
   177  		}
   178  	})
   179  
   180  	ginkgo.Context("testing 'kpm add '", func() {
   181  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "kpm_add")
   182  		testSuites := LoadAllTestSuites(testSuitesRoot)
   183  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
   184  		for _, ts := range testSuites {
   185  			ts := ts
   186  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
   187  				workspace := GetWorkspace()
   188  				CopyDir(filepath.Join(testDataRoot, ts.Name), filepath.Join(workspace, ts.Name))
   189  
   190  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", filepath.Join(workspace, ts.Name))
   191  				stdout, stderr, err := ExecKpmWithWorkDir(input, filepath.Join(workspace, ts.Name))
   192  
   193  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   194  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   195  
   196  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   197  				gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   198  				gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   199  			})
   200  		}
   201  	})
   202  
   203  	ginkgo.Context("testing 'kpm metadata '", func() {
   204  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "kpm_metadata")
   205  		testSuites := LoadAllTestSuites(testSuitesRoot)
   206  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
   207  		for _, ts := range testSuites {
   208  			ts := ts
   209  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
   210  				workspace := GetWorkspace()
   211  
   212  				CopyDir(filepath.Join(testDataRoot, ts.Name), filepath.Join(workspace, ts.Name))
   213  
   214  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", filepath.Join(workspace, ts.Name))
   215  				stdout, stderr, err := ExecKpmWithWorkDir(input, filepath.Join(workspace, ts.Name))
   216  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   217  
   218  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   219  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   220  
   221  				home, err := os.UserHomeDir()
   222  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   223  				expectedStdout = ReplaceAllKeyByValue(expectedStdout, "<user_home>", home)
   224  				expectedStderr = ReplaceAllKeyByValue(expectedStderr, "<user_home>", home)
   225  
   226  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   227  				gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   228  				gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   229  			})
   230  		}
   231  	})
   232  
   233  	ginkgo.Context("testing 'test oci '", func() {
   234  		testSuitesRoot := filepath.Join(filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "kpm"), "test_oci")
   235  		testSuites := LoadAllTestSuites(testSuitesRoot)
   236  		testDataRoot := filepath.Join(filepath.Join(GetWorkDir(), TEST_SUITES_DIR), "test_data")
   237  		for _, ts := range testSuites {
   238  			ts := ts
   239  			ginkgo.It(ts.GetTestSuiteInfo(), func() {
   240  				// 1. Push a package with metadata in OCI manifest
   241  				workspace := GetWorkspace()
   242  
   243  				CopyDir(filepath.Join(testDataRoot, ts.Name), filepath.Join(workspace, ts.Name))
   244  
   245  				input := ReplaceAllKeyByValue(ts.Input, "<workspace>", filepath.Join(workspace, ts.Name))
   246  				stdout, stderr, err := ExecKpmWithWorkDir(input, filepath.Join(workspace, ts.Name))
   247  
   248  				expectedStdout := ReplaceAllKeyByValue(ts.ExpectStdout, "<workspace>", workspace)
   249  				expectedStderr := ReplaceAllKeyByValue(ts.ExpectStderr, "<workspace>", workspace)
   250  
   251  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   252  				if !IsIgnore(expectedStdout) {
   253  					gomega.Expect(stdout).To(gomega.ContainSubstring(expectedStdout))
   254  				}
   255  				if !IsIgnore(expectedStderr) {
   256  					gomega.Expect(stderr).To(gomega.ContainSubstring(expectedStderr))
   257  				}
   258  
   259  				bytes, err := os.ReadFile(filepath.Join(testDataRoot, "expected_oci_manifest.json"))
   260  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   261  
   262  				// 2. fetch the metadata in OCI manifest to check if the metadata is correct
   263  				repo, err := remote.NewRepository("localhost:5001/test/test_push_with_oci_manifest")
   264  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   265  				repo.PlainHTTP = true
   266  				repo.Client = &auth.Client{
   267  					Client: retry.DefaultClient,
   268  					Cache:  auth.DefaultCache,
   269  					Credential: auth.StaticCredential("localhost:5001", auth.Credential{
   270  						Username: "test",
   271  						Password: "1234",
   272  					}),
   273  				}
   274  
   275  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   276  				_, manifestContent, err := oras.FetchBytes(context.Background(), repo, "0.0.1", oras.DefaultFetchBytesOptions)
   277  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   278  				var manifest_got v1.Manifest
   279  				err = json.Unmarshal([]byte(manifestContent), &manifest_got)
   280  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   281  
   282  				var manifest_expect v1.Manifest
   283  				err = json.Unmarshal(bytes, &manifest_expect)
   284  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   285  				gomega.Expect(len(manifest_expect.Annotations)).To(gomega.Equal(len(manifest_got.Annotations)))
   286  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_NAME]).
   287  					To(gomega.Equal(manifest_got.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_NAME]))
   288  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_VERSION]).
   289  					To(gomega.Equal(manifest_got.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_VERSION]))
   290  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_DESCRIPTION]).
   291  					To(gomega.Equal(manifest_got.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_DESCRIPTION]))
   292  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_SUM]).
   293  					To(gomega.Equal(manifest_got.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_SUM]))
   294  			})
   295  
   296  			ginkgo.It("testing 'fetch api '", func() {
   297  				kpmcli, err := client.NewKpmClient()
   298  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   299  				jsonstr, err := kpmcli.FetchOciManifestIntoJsonStr(opt.OciFetchOptions{
   300  					FetchBytesOptions: oras.DefaultFetchBytesOptions,
   301  					OciOptions: opt.OciOptions{
   302  						Reg:  "localhost:5001",
   303  						Repo: "test/kcl2",
   304  						Tag:  "0.0.1",
   305  					},
   306  				})
   307  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   308  				var manifest_expect v1.Manifest
   309  				err = json.Unmarshal([]byte(jsonstr), &manifest_expect)
   310  				gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
   311  				gomega.Expect(len(manifest_expect.Annotations)).To(gomega.Equal(5))
   312  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_NAME]).To(gomega.Equal("kcl2"))
   313  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_VERSION]).To(gomega.Equal("0.0.1"))
   314  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_DESCRIPTION]).To(gomega.Equal("This is the kcl package named kcl2"))
   315  				gomega.Expect(manifest_expect.Annotations[constants.DEFAULT_KCL_OCI_MANIFEST_SUM]).To(gomega.Equal("Y/QXruiaxcJcmOnKWl4UEFuUqKTtbi4jTTeuEjeGV8s="))
   316  			})
   317  		}
   318  	})
   319  })