github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/commands/buildinfo/addgit_test.go (about)

     1  package buildinfo
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
     6  	testsutils "github.com/jfrog/jfrog-client-go/utils/tests"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  	"os"
    10  	"path/filepath"
    11  	"strconv"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/jfrog/jfrog-cli-core/artifactory/utils"
    17  	"github.com/jfrog/jfrog-cli-core/utils/coreutils"
    18  	"github.com/jfrog/jfrog-cli-core/utils/log"
    19  	"github.com/jfrog/jfrog-cli-core/utils/tests"
    20  	"github.com/jfrog/jfrog-client-go/artifactory/buildinfo"
    21  )
    22  
    23  const (
    24  	withGit    = "git_test_.git_suffix"
    25  	withoutGit = "git_test_no_.git_suffix"
    26  	withBranch = "git_issues2_.git_suffix"
    27  	buildName  = "TestExtractGitUrl"
    28  )
    29  
    30  func init() {
    31  	log.SetDefaultLogger()
    32  }
    33  
    34  func TestExtractGitUrlWithDotGit(t *testing.T) {
    35  	runTest(t, withGit)
    36  }
    37  
    38  func TestExtractGitUrlWithoutDotGit(t *testing.T) {
    39  	runTest(t, withoutGit)
    40  }
    41  
    42  func runTest(t *testing.T, originalDir string) {
    43  	baseDir, dotGitPath := tests.PrepareDotGitDir(t, originalDir, filepath.Join("..", "testdata"))
    44  	buildDir := getBuildDir(t)
    45  	defer cleanUp(t, buildDir, dotGitPath, originalDir)
    46  	err := runBuildAddGit(t, buildName, "1", baseDir, true)
    47  	if err != nil {
    48  		return
    49  	}
    50  	partials := getBuildInfoPartials(t, buildName, "1", "")
    51  	checkVCSUrl(partials, t)
    52  }
    53  
    54  func TestBuildAddGitSubmodules(t *testing.T) {
    55  	var projectPath, tmpDir string
    56  	projectPath, tmpDir = testsutils.InitVcsSubmoduleTestDir(t, filepath.Join("..", "testdata", "git_test_submodule"))
    57  	defer fileutils.RemoveTempDir(tmpDir)
    58  
    59  	testsName := []string{"dotGitProvided", "dotGitSearched"}
    60  	for _, test := range testsName {
    61  		t.Run(test, func(t *testing.T) {
    62  			tmpBuildName := test + "-Build-" + strconv.FormatInt(time.Now().Unix(), 10)
    63  			err := runBuildAddGit(t, tmpBuildName, "1", projectPath, test == "dotGitProvided")
    64  			require.NoError(t, err)
    65  			partials := getBuildInfoPartials(t, tmpBuildName, "1", "")
    66  			assertVcsSubmodules(t, partials)
    67  		})
    68  	}
    69  }
    70  
    71  func TestBuildAddGitVCSDetails(t *testing.T) {
    72  	bagTests := []struct {
    73  		name        string
    74  		originalDir string
    75  		revision    string
    76  		branch      string
    77  		message     string
    78  	}{
    79  		{"Test vcs details without branch", withGit, "6198a6294722fdc75a570aac505784d2ec0d1818", "", "TEST-2 - Adding text to file1.txt"},
    80  		{"Test vcs details with branch", withBranch, "b033a0e508bdb52eee25654c9e12db33ff01b8ff", "master", "TEST-4 - Adding text to file2.txt"}}
    81  
    82  	for _, test := range bagTests {
    83  		t.Run(test.name, func(t *testing.T) {
    84  			baseDir, dotGitPath := tests.PrepareDotGitDir(t, test.originalDir, filepath.Join("..", "testdata"))
    85  			buildDir := getBuildDir(t)
    86  			defer cleanUp(t, buildDir, dotGitPath, test.originalDir)
    87  			err := runBuildAddGit(t, buildName, "1", baseDir, true)
    88  			if err != nil {
    89  				return
    90  			}
    91  			partials := getBuildInfoPartials(t, buildName, "1", "")
    92  			assertVCSDetails(partials, test.revision, test.branch, test.message, t)
    93  		})
    94  	}
    95  }
    96  
    97  func assertVCSDetails(partials buildinfo.Partials, revision, branch, message string, t *testing.T) {
    98  	for _, partial := range partials {
    99  		if partial.VcsList != nil {
   100  			for _, vcs := range partial.VcsList {
   101  				assert.Equal(t, revision, vcs.Revision)
   102  				assert.Equal(t, branch, vcs.Branch)
   103  				assert.Equal(t, message, vcs.Message)
   104  			}
   105  		} else {
   106  			t.Error("VCS cannot be nil")
   107  			break
   108  		}
   109  	}
   110  }
   111  
   112  func assertVcsSubmodules(t *testing.T, partials buildinfo.Partials) {
   113  	assert.Len(t, partials, 1)
   114  	vcsList := partials[0].VcsList
   115  	assert.NotNil(t, vcsList)
   116  	assert.Len(t, vcsList, 1)
   117  	curVcs := vcsList[0]
   118  	assert.Equal(t, "https://github.com/jfrog/jfrog-cli.git", curVcs.Url)
   119  	assert.Equal(t, "6198a6294722fdc75a570aac505784d2ec0d1818", curVcs.Revision)
   120  	assert.Equal(t, "submodule", curVcs.Branch)
   121  	assert.Equal(t, "TEST-2 - Adding text to file1.txt", curVcs.Message)
   122  }
   123  
   124  func cleanUp(t *testing.T, buildDir, dotGitPath, originalDir string) {
   125  	if buildDir != "" {
   126  		tests.RemovePath(buildDir, t)
   127  	}
   128  	if dotGitPath != "" {
   129  		tests.RenamePath(dotGitPath, filepath.Join("..", "testdata", originalDir), t)
   130  	}
   131  }
   132  
   133  func getBuildInfoPartials(t *testing.T, buildName, buildNumber, projectKey string) buildinfo.Partials {
   134  	partials, err := utils.ReadPartialBuildInfoFiles(buildName, buildNumber, projectKey)
   135  	if err != nil {
   136  		assert.NoError(t, err)
   137  		return nil
   138  	}
   139  	return partials
   140  }
   141  
   142  // Run BAG command. If setDotGit==true, provide baseDir to the command. Else, change wd to baseDir and make the command find .git manually.
   143  func runBuildAddGit(t *testing.T, buildName, buildNumber string, baseDir string, setDotGit bool) error {
   144  	buildAddGitConfiguration := new(BuildAddGitCommand).SetBuildConfiguration(&utils.BuildConfiguration{BuildName: buildName, BuildNumber: buildNumber})
   145  	if setDotGit {
   146  		buildAddGitConfiguration.SetDotGitPath(baseDir)
   147  	} else {
   148  		wd, err := os.Getwd()
   149  		if err != nil {
   150  			assert.Error(t, err)
   151  			return err
   152  		}
   153  		defer os.Chdir(wd)
   154  
   155  		err = os.Chdir(baseDir)
   156  		if err != nil {
   157  			assert.Error(t, err)
   158  			return err
   159  		}
   160  	}
   161  	err := buildAddGitConfiguration.Run()
   162  	assert.NoError(t, err)
   163  	return err
   164  }
   165  
   166  func getBuildDir(t *testing.T) string {
   167  	buildDir, err := utils.GetBuildDir(buildName, "1", "")
   168  	if err != nil {
   169  		t.Error("Cannot create temp dir due to: " + err.Error())
   170  		return ""
   171  	}
   172  	return buildDir
   173  }
   174  
   175  func checkVCSUrl(partials buildinfo.Partials, t *testing.T) {
   176  	for _, partial := range partials {
   177  		if partial.VcsList != nil {
   178  			for _, vcs := range partial.VcsList {
   179  				url := vcs.Url
   180  				urlSplitted := strings.Split(url, ".git")
   181  				if len(urlSplitted) != 2 {
   182  					t.Error("Arguments value is different than two: ", urlSplitted)
   183  					break
   184  				}
   185  			}
   186  		} else {
   187  			t.Error("VCS cannot be nil")
   188  			break
   189  		}
   190  	}
   191  }
   192  
   193  func TestPopulateIssuesConfigurations(t *testing.T) {
   194  	// Test success scenario
   195  	expectedIssuesConfiguration := &IssuesConfiguration{
   196  		ServerID:          "local",
   197  		TrackerName:       "TESTING",
   198  		TrackerUrl:        "http://TESTING.com",
   199  		Regexp:            `([a-zA-Z]+-[0-9]*)\s-\s(.*)`,
   200  		KeyGroupIndex:     1,
   201  		SummaryGroupIndex: 2,
   202  		Aggregate:         true,
   203  		AggregationStatus: "RELEASE",
   204  		LogLimit:          100,
   205  	}
   206  	ic := new(IssuesConfiguration)
   207  	// Build config from file
   208  	err := ic.populateIssuesConfigsFromSpec(filepath.Join("..", "testdata", "buildissues", "issuesconfig_success.yaml"))
   209  	// Check they are equal
   210  	if err != nil {
   211  		t.Error(fmt.Sprintf("Reading configurations file ended with error: %s", err.Error()))
   212  		t.FailNow()
   213  	}
   214  	if *ic != *expectedIssuesConfiguration {
   215  		t.Error(fmt.Sprintf("Failed reading configurations file. Expected: %+v Received: %+v", *expectedIssuesConfiguration, *ic))
   216  		t.FailNow()
   217  	}
   218  
   219  	// Test failing scenarios
   220  	failing := []string{
   221  		filepath.Join("..", "testdata", "buildissues", "issuesconfig_fail_no_issues.yaml"),
   222  		filepath.Join("..", "testdata", "buildissues", "issuesconfig_fail_invalid_groupindex.yaml"),
   223  		filepath.Join("..", "testdata", "buildissues", "issuesconfig_fail_invalid_aggregate.yaml"),
   224  	}
   225  
   226  	for _, config := range failing {
   227  		err = ic.populateIssuesConfigsFromSpec(config)
   228  		if err == nil {
   229  			t.Error(fmt.Sprintf("Reading configurations file was supposed to end with error: %s", config))
   230  			t.FailNow()
   231  		}
   232  	}
   233  }
   234  
   235  func TestAddGitDoCollect(t *testing.T) {
   236  	// Create git folder with files
   237  	originalFolder := "git_issues_.git_suffix"
   238  	baseDir, dotGitPath := tests.PrepareDotGitDir(t, originalFolder, filepath.Join("..", "testdata"))
   239  
   240  	// Create BuildAddGitCommand
   241  	config := BuildAddGitCommand{
   242  		issuesConfig: &IssuesConfiguration{
   243  			LogLimit:          100,
   244  			Aggregate:         false,
   245  			SummaryGroupIndex: 2,
   246  			KeyGroupIndex:     1,
   247  			Regexp:            `(.+-[0-9]+)\s-\s(.+)`,
   248  			TrackerName:       "test",
   249  		},
   250  		buildConfiguration: &utils.BuildConfiguration{BuildNumber: "1", BuildName: "cli-tests-rt-build1"},
   251  		configFilePath:     "",
   252  		dotGitPath:         dotGitPath,
   253  	}
   254  
   255  	// Collect issues
   256  	issues, err := config.DoCollect(config.issuesConfig, "")
   257  	if err != nil {
   258  		t.Error(err)
   259  	}
   260  	if len(issues) != 2 {
   261  		// Error - should be empty
   262  		t.Errorf("Issues list expected to have 2 issues, instead found %d issues: %v", len(issues), issues)
   263  	}
   264  
   265  	// Clean previous git path
   266  	tests.RenamePath(dotGitPath, filepath.Join(baseDir, originalFolder), t)
   267  	// Check if needs to fail
   268  	if t.Failed() {
   269  		t.FailNow()
   270  	}
   271  	// Set new git path
   272  	originalFolder = "git_issues2_.git_suffix"
   273  	baseDir, dotGitPath = tests.PrepareDotGitDir(t, originalFolder, filepath.Join("..", "testdata"))
   274  
   275  	// Collect issues - we pass a revision, so only 2 of the 4 existing issues should be collected
   276  	issues, err = config.DoCollect(config.issuesConfig, "6198a6294722fdc75a570aac505784d2ec0d1818")
   277  	if err != nil {
   278  		t.Error(err)
   279  	}
   280  	if len(issues) != 2 {
   281  		// Error - should find 2 issues
   282  		t.Errorf("Issues list expected to have 2 issues, instead found %d issues: %v", len(issues), issues)
   283  	}
   284  
   285  	// Test collection with a made up revision - the command should not throw an error, and 0 issues should be returned.
   286  	issues, err = config.DoCollect(config.issuesConfig, "abcdefABCDEF1234567890123456789012345678")
   287  	assert.NoError(t, err)
   288  	assert.Empty(t, issues)
   289  
   290  	// Clean git path
   291  	tests.RenamePath(dotGitPath, filepath.Join(baseDir, originalFolder), t)
   292  }
   293  
   294  func TestServerDetailsFromConfigFile(t *testing.T) {
   295  	expectedUrl := "http://localhost:8081/artifactory/"
   296  	expectedUser := "admin"
   297  
   298  	homeEnv := os.Getenv(coreutils.HomeDir)
   299  	if homeEnv == "" {
   300  		homeEnv = os.Getenv(coreutils.JfrogHomeEnv)
   301  	}
   302  	defer os.Setenv(coreutils.HomeDir, homeEnv)
   303  	baseDir, err := os.Getwd()
   304  	if err != nil {
   305  		t.Error(err)
   306  	}
   307  	err = os.Setenv(coreutils.HomeDir, filepath.Join(baseDir, "..", "testdata"))
   308  	if err != nil {
   309  		t.Error(err)
   310  	}
   311  	configFilePath := filepath.Join("..", "testdata", "buildissues", "issuesconfig_success.yaml")
   312  	config := BuildAddGitCommand{
   313  		configFilePath: configFilePath,
   314  	}
   315  	details, err := config.ServerDetails()
   316  	if err != nil {
   317  		t.Error(err)
   318  	}
   319  
   320  	if details.ArtifactoryUrl != expectedUrl {
   321  		t.Error(fmt.Sprintf("Expected %s, got %s", expectedUrl, details.ArtifactoryUrl))
   322  	}
   323  	if details.User != expectedUser {
   324  		t.Error(fmt.Sprintf("Expected %s, got %s", details.User, expectedUser))
   325  	}
   326  }
   327  
   328  func TestServerDetailsWithoutConfigFile(t *testing.T) {
   329  	expectedUrl := "http://localhost:8082/artifactory/"
   330  	expectedUser := "admin2"
   331  
   332  	homeEnv := os.Getenv(coreutils.HomeDir)
   333  	if homeEnv == "" {
   334  		homeEnv = os.Getenv(coreutils.JfrogHomeEnv)
   335  	}
   336  	defer os.Setenv(coreutils.HomeDir, homeEnv)
   337  
   338  	baseDir, err := os.Getwd()
   339  	if err != nil {
   340  		t.Error(err)
   341  	}
   342  	err = os.Setenv(coreutils.HomeDir, filepath.Join(baseDir, "..", "testdata"))
   343  	if err != nil {
   344  		t.Error(err)
   345  	}
   346  
   347  	config := BuildAddGitCommand{}
   348  	details, err := config.ServerDetails()
   349  	if err != nil {
   350  		t.Error(err)
   351  	}
   352  
   353  	if details.ArtifactoryUrl != expectedUrl {
   354  		t.Error(fmt.Sprintf("Expected %s, got %s", expectedUrl, details.ArtifactoryUrl))
   355  	}
   356  
   357  	if details.User != expectedUser {
   358  		t.Error(fmt.Sprintf("Expected %s, got %s", details.User, expectedUser))
   359  	}
   360  }