github.com/jfrog/jfrog-cli@v1.54.1/plugins_test.go (about)

     1  package main
     2  
     3  import (
     4  	"github.com/buger/jsonparser"
     5  	"github.com/jfrog/jfrog-cli-core/plugins"
     6  	"github.com/jfrog/jfrog-cli-core/utils/coreutils"
     7  	coreTests "github.com/jfrog/jfrog-cli-core/utils/tests"
     8  	"github.com/jfrog/jfrog-cli/plugins/commands/utils"
     9  	"github.com/jfrog/jfrog-cli/utils/cliutils"
    10  	"github.com/jfrog/jfrog-cli/utils/tests"
    11  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
    12  	"github.com/stretchr/testify/assert"
    13  	"io"
    14  	"os"
    15  	"path/filepath"
    16  	"strings"
    17  	"testing"
    18  )
    19  
    20  const officialPluginForTest = "rt-fs"
    21  const officialPluginVersion = "v1.0.0"
    22  const customPluginName = "custom-plugin"
    23  
    24  func TestPluginInstallUninstallOfficialRegistry(t *testing.T) {
    25  	initPluginsTest(t)
    26  	// Create temp jfrog home
    27  	coreTests.CleanUnitTestsJfrogHome()
    28  	oldHome, err := coreTests.SetJfrogHome()
    29  	if err != nil {
    30  		return
    31  	}
    32  	defer os.Setenv(coreutils.HomeDir, oldHome)
    33  	defer coreTests.CleanUnitTestsJfrogHome()
    34  
    35  	// Set empty plugins server to run against official registry.
    36  	oldServer := os.Getenv(utils.PluginsServerEnv)
    37  	defer os.Setenv(utils.PluginsServerEnv, oldServer)
    38  	assert.NoError(t, os.Setenv(utils.PluginsServerEnv, ""))
    39  	oldRepo := os.Getenv(utils.PluginsRepoEnv)
    40  	defer os.Setenv(utils.PluginsRepoEnv, oldRepo)
    41  	assert.NoError(t, os.Setenv(utils.PluginsRepoEnv, ""))
    42  
    43  	jfrogCli := tests.NewJfrogCli(execMain, "jfrog", "")
    44  
    45  	// Try installing a plugin with specific version.
    46  	err = installAndAssertPlugin(t, jfrogCli, officialPluginForTest, officialPluginVersion)
    47  	if err != nil {
    48  		return
    49  	}
    50  
    51  	// Try installing the latest version of the plugin. Also verifies replacement was successful.
    52  	err = installAndAssertPlugin(t, jfrogCli, officialPluginForTest, "")
    53  	if err != nil {
    54  		return
    55  	}
    56  
    57  	// Uninstall plugin from home dir.
    58  	err = jfrogCli.Exec("plugin", "uninstall", officialPluginForTest)
    59  	if err != nil {
    60  		assert.NoError(t, err)
    61  		return
    62  	}
    63  	err = verifyPluginInPluginsDir(t, officialPluginForTest, false)
    64  	if err != nil {
    65  		return
    66  	}
    67  }
    68  
    69  func installAndAssertPlugin(t *testing.T, jfrogCli *tests.JfrogCli, pluginName, pluginVersion string) error {
    70  	// If version required, concat to plugin name
    71  	identifier := pluginName
    72  	if pluginVersion != "" {
    73  		identifier += "@" + pluginVersion
    74  	}
    75  
    76  	// Install plugin from registry.
    77  	err := jfrogCli.Exec("plugin", "install", identifier)
    78  	if err != nil {
    79  		assert.NoError(t, err)
    80  		return err
    81  	}
    82  	err = verifyPluginInPluginsDir(t, pluginName, true)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	err = verifyPluginSignature(t, jfrogCli)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	return verifyPluginVersion(t, jfrogCli, pluginVersion)
    93  }
    94  
    95  func verifyPluginSignature(t *testing.T, jfrogCli *tests.JfrogCli) error {
    96  	// Get signature from plugin.
    97  	content, err := getCmdOutput(t, jfrogCli, officialPluginForTest, plugins.SignatureCommandName)
    98  	if err != nil {
    99  		return err
   100  	}
   101  
   102  	// Extract the the name from the output.
   103  	name, err := jsonparser.GetString(content, "name")
   104  	if err != nil {
   105  		assert.NoError(t, err)
   106  		return err
   107  	}
   108  	assert.Equal(t, officialPluginForTest, name)
   109  
   110  	// Extract the the usage from the output.
   111  	usage, err := jsonparser.GetString(content, "usage")
   112  	if err != nil {
   113  		assert.NoError(t, err)
   114  		return err
   115  	}
   116  	assert.NotEmpty(t, usage)
   117  	return nil
   118  }
   119  
   120  func verifyPluginVersion(t *testing.T, jfrogCli *tests.JfrogCli, expectedVersion string) error {
   121  	// Run plugin's -v command.
   122  	content, err := getCmdOutput(t, jfrogCli, officialPluginForTest, "-v")
   123  	if err != nil {
   124  		return err
   125  	}
   126  	if expectedVersion != "" {
   127  		assert.NoError(t, utils.AssertPluginVersion(string(content), expectedVersion))
   128  	}
   129  	return err
   130  }
   131  
   132  func getCmdOutput(t *testing.T, jfrogCli *tests.JfrogCli, cmd ...string) ([]byte, error) {
   133  	oldStdout := os.Stdout
   134  	r, w, err := os.Pipe()
   135  	if err != nil {
   136  		assert.NoError(t, err)
   137  		return nil, err
   138  	}
   139  	os.Stdout = w
   140  	defer func() {
   141  		os.Stdout = oldStdout
   142  		r.Close()
   143  	}()
   144  	err = jfrogCli.Exec(cmd...)
   145  	if err != nil {
   146  		assert.NoError(t, err)
   147  		w.Close()
   148  		return nil, err
   149  	}
   150  	err = w.Close()
   151  	if err != nil {
   152  		assert.NoError(t, err)
   153  		return nil, err
   154  	}
   155  	content, err := io.ReadAll(r)
   156  	assert.NoError(t, err)
   157  	return content, err
   158  }
   159  
   160  func verifyPluginInPluginsDir(t *testing.T, pluginName string, shouldExist bool) error {
   161  	pluginsDir, err := coreutils.GetJfrogPluginsDir()
   162  	if err != nil {
   163  		assert.NoError(t, err)
   164  		return err
   165  	}
   166  
   167  	actualExists, err := fileutils.IsFileExists(filepath.Join(pluginsDir, utils.GetLocalPluginExecutableName(pluginName)), false)
   168  	if err != nil {
   169  		assert.NoError(t, err)
   170  		return err
   171  	}
   172  	if shouldExist {
   173  		assert.True(t, actualExists, "expected plugin executable to be preset in plugins dir after installing")
   174  	} else {
   175  		assert.False(t, actualExists, "expected plugin executable not to be preset in plugins dir after uninstalling")
   176  	}
   177  	return nil
   178  }
   179  
   180  func initPluginsTest(t *testing.T) {
   181  	if !*tests.TestPlugins {
   182  		t.Skip("Skipping Plugins test. To run Plugins test add the '-test.plugins=true' option.")
   183  	}
   184  }
   185  
   186  func TestPublishInstallCustomServer(t *testing.T) {
   187  	initPluginsTest(t)
   188  	// Create temp jfrog home
   189  	coreTests.CleanUnitTestsJfrogHome()
   190  	oldHome, err := coreTests.SetJfrogHome()
   191  	if err != nil {
   192  		return
   193  	}
   194  	defer os.Setenv(coreutils.HomeDir, oldHome)
   195  	defer coreTests.CleanUnitTestsJfrogHome()
   196  
   197  	jfrogCli := tests.NewJfrogCli(execMain, "jfrog", "")
   198  
   199  	// Create server to use with the command.
   200  	_, err = createServerConfigAndReturnPassphrase()
   201  	defer deleteServerConfig()
   202  	if err != nil {
   203  		assert.NoError(t, err)
   204  		return
   205  	}
   206  
   207  	// Set plugins server to run against the configured server.
   208  	oldServer := os.Getenv(utils.PluginsServerEnv)
   209  	defer os.Setenv(utils.PluginsServerEnv, oldServer)
   210  	assert.NoError(t, os.Setenv(utils.PluginsServerEnv, tests.RtServerId))
   211  	oldRepo := os.Getenv(utils.PluginsRepoEnv)
   212  	defer os.Setenv(utils.PluginsRepoEnv, oldRepo)
   213  	assert.NoError(t, os.Setenv(utils.PluginsRepoEnv, tests.RtRepo1))
   214  
   215  	err = setOnlyLocalArc(t)
   216  	if err != nil {
   217  		return
   218  	}
   219  
   220  	// Publish the CLI as a plugin to the registry.
   221  	err = jfrogCli.Exec("plugin", "p", customPluginName, cliutils.GetVersion())
   222  	if err != nil {
   223  		assert.NoError(t, err)
   224  		return
   225  	}
   226  
   227  	err = verifyPluginExistsInRegistry(t)
   228  	if err != nil {
   229  		return
   230  	}
   231  
   232  	// Install plugin from registry.
   233  	err = jfrogCli.Exec("plugin", "install", customPluginName)
   234  	if err != nil {
   235  		assert.NoError(t, err)
   236  		return
   237  	}
   238  	err = verifyPluginInPluginsDir(t, customPluginName, true)
   239  	if err != nil {
   240  		return
   241  	}
   242  	pluginsDir, err := coreutils.GetJfrogPluginsDir()
   243  	if err != nil {
   244  		assert.NoError(t, err)
   245  		return
   246  	}
   247  	assert.NoError(t, os.Remove(filepath.Join(pluginsDir, utils.GetLocalPluginExecutableName(customPluginName))))
   248  }
   249  
   250  func verifyPluginExistsInRegistry(t *testing.T) error {
   251  	searchFilePath, err := tests.CreateSpec(tests.SearchAllRepo1)
   252  	if err != nil {
   253  		assert.NoError(t, err)
   254  		return err
   255  	}
   256  	localArc, err := utils.GetLocalArchitecture()
   257  	if err != nil {
   258  		assert.NoError(t, err)
   259  		return err
   260  	}
   261  	expectedPath := utils.GetPluginPathInArtifactory(customPluginName, cliutils.GetVersion(), localArc)
   262  	// Expected to find the plugin in the version and latest dir.
   263  	expected := []string{
   264  		expectedPath,
   265  		strings.Replace(expectedPath, cliutils.GetVersion(), utils.LatestVersionName, 1),
   266  	}
   267  	verifyExistInArtifactory(expected, searchFilePath, t)
   268  	return nil
   269  }
   270  
   271  // Set the local architecture to be the only one in map to avoid building for all architectures.
   272  func setOnlyLocalArc(t *testing.T) error {
   273  	localArcName, err := utils.GetLocalArchitecture()
   274  	if err != nil {
   275  		assert.NoError(t, err)
   276  		return err
   277  	}
   278  	localArc := utils.ArchitecturesMap[localArcName]
   279  	utils.ArchitecturesMap = map[string]utils.Architecture{
   280  		localArcName: localArc,
   281  	}
   282  	return nil
   283  }
   284  
   285  func InitPluginsTests() {
   286  	initArtifactoryCli()
   287  	cleanUpOldRepositories()
   288  	tests.AddTimestampToGlobalVars()
   289  	createRequiredRepos()
   290  }
   291  
   292  func CleanPluginsTests() {
   293  	deleteCreatedRepos()
   294  }