github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/test/integration/artifacts_int_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"encoding/json"
     5  	"path/filepath"
     6  	"runtime"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/ActiveState/cli/internal/constants"
    11  	"github.com/ActiveState/cli/internal/locale"
    12  	"github.com/ActiveState/cli/internal/runners/artifacts"
    13  	"github.com/ActiveState/cli/internal/testhelpers/suite"
    14  	"github.com/ActiveState/termtest"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/ActiveState/cli/internal/testhelpers/e2e"
    18  	"github.com/ActiveState/cli/internal/testhelpers/tagsuite"
    19  )
    20  
    21  type ArtifactsIntegrationTestSuite struct {
    22  	tagsuite.Suite
    23  }
    24  
    25  func (suite *ArtifactsIntegrationTestSuite) TestArtifacts() {
    26  	suite.OnlyRunForTags(tagsuite.Artifacts)
    27  	ts := e2e.New(suite.T(), false)
    28  	defer ts.Close()
    29  
    30  	ts.PrepareProject("ActiveState-CLI/Python-With-Custom-Builds", "993454c7-6613-4b1a-8981-1cee43cc249e")
    31  
    32  	cp := ts.SpawnWithOpts(
    33  		e2e.OptArgs("refresh"),
    34  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
    35  	)
    36  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
    37  
    38  	// In order to reuse the runtime cache and reduce test time we run the rest in subtests
    39  
    40  	suite.Run("no flags", func() {
    41  		cp = ts.Spawn("artifacts")
    42  		cp.Expect("Operating on project ActiveState-CLI/Python-With-Custom-Builds, located at")
    43  		cp.Expect("CentOS")
    44  		cp.Expect("Docker Image")
    45  		cp.Expect("Installer")
    46  		cp.Expect("macOS")
    47  		cp.Expect("No artifacts")
    48  		cp.Expect("Windows")
    49  		cp.Expect("Signed Installer")
    50  		cp.Expect(".exe")
    51  		cp.Expect("To download artifacts run")
    52  		cp.ExpectExitCode(0)
    53  	})
    54  
    55  	suite.Run("--all flag", func() {
    56  		cp = ts.Spawn("artifacts", "--all")
    57  		cp.Expect("CentOS")
    58  		cp.Expect("Docker Image")
    59  		cp.Expect("Installer")
    60  		cp.Expect("Packages")
    61  		cp.Expect("python@3")
    62  		cp.Expect("macOS")
    63  		cp.Expect("Windows")
    64  		cp.Expect("Signed Installer")
    65  		cp.Expect("Packages")
    66  		cp.Expect("python@3")
    67  		cp.Expect("To download artifacts run")
    68  		cp.ExpectExitCode(0)
    69  	})
    70  
    71  	suite.Run("json without flags", func() {
    72  		cp = ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json"), e2e.OptTermTest(termtest.OptRows(100)))
    73  		cp.ExpectExitCode(0)
    74  
    75  		output := artifacts.StructuredOutput{}
    76  		out := strings.TrimLeft(cp.StrippedSnapshot(), locale.T("notice_runtime_disabled"))
    77  		suite.Require().NoError(json.Unmarshal([]byte(out), &output), ts.DebugMessage(""))
    78  
    79  		suite.Equal(3, len(output.Platforms))
    80  		for _, platform := range output.Platforms {
    81  			if !strings.HasPrefix(platform.Name, "macOS") {
    82  				suite.Greater(len(platform.Artifacts), 0)
    83  			}
    84  			suite.Equal(0, len(platform.Packages))
    85  		}
    86  	})
    87  
    88  	suite.Run("json with --all flag", func() {
    89  		cp = ts.SpawnWithOpts(e2e.OptArgs("artifacts", "--output=json", "--all"), e2e.OptTermTest(termtest.OptRows(100)))
    90  		cp.ExpectExitCode(0)
    91  
    92  		output := artifacts.StructuredOutput{}
    93  		out := strings.TrimLeft(cp.StrippedSnapshot(), locale.T("notice_runtime_disabled"))
    94  		suite.Require().NoError(json.Unmarshal([]byte(out), &output), ts.DebugMessage(""))
    95  
    96  		suite.Equal(3, len(output.Platforms))
    97  		for _, platform := range output.Platforms {
    98  			if !strings.HasPrefix(platform.Name, "macOS") {
    99  				suite.Greater(len(platform.Artifacts), 0)
   100  			}
   101  			suite.Greater(len(platform.Packages), 0)
   102  		}
   103  	})
   104  }
   105  
   106  func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Remote() {
   107  	suite.OnlyRunForTags(tagsuite.Artifacts)
   108  	ts := e2e.New(suite.T(), false)
   109  	defer ts.Close()
   110  
   111  	suite.Run("Namespace only", func() {
   112  		cp := ts.Spawn("artifacts", "--namespace", "ActiveState-CLI/Python-With-Custom-Builds")
   113  		cp.Expect("CentOS")
   114  		cp.Expect("Docker Image")
   115  		cp.Expect("Installer")
   116  		cp.Expect("macOS")
   117  		cp.Expect("No artifacts")
   118  		cp.Expect("Windows")
   119  		cp.Expect("Signed Installer")
   120  		cp.Expect(".exe")
   121  		cp.Expect("To download artifacts run")
   122  		suite.Assert().NotContains(cp.Snapshot(), "Operating on project")
   123  		cp.ExpectExitCode(0)
   124  	})
   125  
   126  	suite.Run("Namespace and commit ID", func() {
   127  		cp := ts.Spawn("artifacts", "--namespace", "ActiveState-CLI/Python-With-Custom-Builds", "--commit", "993454c7-6613-4b1a-8981-1cee43cc249e")
   128  		cp.Expect("CentOS")
   129  		cp.Expect("Docker Image")
   130  		cp.Expect("Installer")
   131  		cp.Expect("macOS")
   132  		cp.Expect("No artifacts")
   133  		cp.Expect("Windows")
   134  		cp.Expect("Signed Installer")
   135  		cp.Expect(".exe")
   136  		cp.Expect("To download artifacts run")
   137  		cp.ExpectExitCode(0)
   138  	})
   139  }
   140  
   141  type Platforms struct {
   142  	Platforms []Platform `json:"platforms"`
   143  }
   144  type Platform struct {
   145  	ID       string   `json:"id"`
   146  	Name     string   `json:"name"`
   147  	Packages Packages `json:"packages"`
   148  }
   149  
   150  type Packages []Build
   151  
   152  type Build struct {
   153  	ID   string `json:"id"`
   154  	Name string `json:"name"`
   155  }
   156  
   157  func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Download() {
   158  	suite.OnlyRunForTags(tagsuite.Artifacts)
   159  	ts := e2e.New(suite.T(), false)
   160  	defer ts.Close()
   161  
   162  	ts.PrepareProject("ActiveState-CLI/Python-With-Custom-Builds", "993454c7-6613-4b1a-8981-1cee43cc249e")
   163  
   164  	cp := ts.SpawnWithOpts(
   165  		e2e.OptArgs("refresh"),
   166  		e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
   167  	)
   168  	cp.ExpectExitCode(0, e2e.RuntimeSourcingTimeoutOpt)
   169  
   170  	var buildID string
   171  	if runtime.GOOS == "windows" {
   172  		// On Windows we need the specific build ID as the terminal buffer is not
   173  		// large enough to display all the builds
   174  		buildID = "dbf05bf8-4b2e-5560-a329-b5b70bc7b0fa"
   175  	} else {
   176  		buildID = suite.extractBuildID(ts, "bzip2@1.0.8", "")
   177  	}
   178  	suite.Require().NotEmpty(buildID)
   179  
   180  	cp = ts.SpawnWithOpts(
   181  		e2e.OptArgs("artifacts", "dl", buildID, "."),
   182  	)
   183  	cp.Expect("Operating on project ActiveState-CLI/Python-With-Custom-Builds, located at")
   184  	cp.Expect("Downloaded bzip2", e2e.RuntimeSourcingTimeoutOpt)
   185  	cp.ExpectExitCode(0)
   186  	require.FileExists(suite.T(), filepath.Join(ts.Dirs.Work, "bzip2-1.0.8.tar.gz"), ts.DebugMessage(""))
   187  }
   188  
   189  func (suite *ArtifactsIntegrationTestSuite) TestArtifacts_Download_Remote() {
   190  	suite.OnlyRunForTags(tagsuite.Artifacts)
   191  	ts := e2e.New(suite.T(), false)
   192  	defer ts.Close()
   193  
   194  	var buildID string
   195  	if runtime.GOOS == "windows" {
   196  		// On Windows we need the specific build ID as the terminal buffer is not
   197  		// large enough to display all the builds
   198  		buildID = "dbf05bf8-4b2e-5560-a329-b5b70bc7b0fa"
   199  	} else {
   200  		buildID = suite.extractBuildID(ts, "bzip2@1.0.8", "ActiveState-CLI/Python-With-Custom-Builds")
   201  	}
   202  	suite.Require().NotEmpty(buildID)
   203  
   204  	cp := ts.Spawn("artifacts", "dl", buildID, ".", "--namespace", "ActiveState-CLI/Python-With-Custom-Builds")
   205  	cp.Expect("Downloaded bzip2", e2e.RuntimeSourcingTimeoutOpt)
   206  	suite.Assert().NotContains(cp.Snapshot(), "Operating on project")
   207  	cp.ExpectExitCode(0)
   208  	require.FileExists(suite.T(), filepath.Join(ts.Dirs.Work, "bzip2-1.0.8.tar.gz"))
   209  }
   210  
   211  func (suite *ArtifactsIntegrationTestSuite) extractBuildID(ts *e2e.Session, name string, namespace string) string {
   212  	args := []string{"builds", "--all", "--output=json"}
   213  	if namespace != "" {
   214  		args = append(args, "--namespace", namespace)
   215  	}
   216  
   217  	cp := ts.SpawnWithOpts(
   218  		e2e.OptArgs(args...),
   219  	)
   220  	cp.Expect(`"}`)
   221  	cp.ExpectExitCode(0)
   222  
   223  	var platforms Platforms
   224  	suite.Require().NoError(json.Unmarshal([]byte(cp.Output()), &platforms))
   225  
   226  	var platformID string
   227  	switch runtime.GOOS {
   228  	case "windows":
   229  		platformID = constants.Win10Bit64UUID
   230  	case "darwin":
   231  		platformID = constants.MacBit64UUID
   232  	case "linux":
   233  		platformID = constants.LinuxBit64UUID
   234  	}
   235  
   236  	for _, platform := range platforms.Platforms {
   237  		if platform.ID != platformID {
   238  			continue
   239  		}
   240  
   241  		for _, build := range platform.Packages {
   242  			if build.Name == name {
   243  				return build.ID
   244  			}
   245  		}
   246  	}
   247  
   248  	return ""
   249  }
   250  
   251  func TestArtifactsIntegrationTestSuite(t *testing.T) {
   252  	suite.Run(t, new(ArtifactsIntegrationTestSuite))
   253  }