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

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