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 }