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