Skip to content

Commit 0aa1695

Browse files
committed
Update config to override correct URL
1 parent 36d4396 commit 0aa1695

File tree

8 files changed

+125
-21
lines changed

8 files changed

+125
-21
lines changed

cmd/state-remote-installer/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ func execute(out output.Outputer, prompt prompt.Prompter, cfg *config.Instance,
208208
version = fmt.Sprintf("%s (%s)", version, channel)
209209
}
210210

211-
update := updater.NewUpdateInstaller(an, availableUpdate)
211+
update := updater.NewUpdateInstaller(cfg, an, availableUpdate)
212212
out.Fprint(os.Stdout, locale.Tl("remote_install_downloading", "• Downloading State Tool version [NOTICE]{{.V0}}[/RESET]... ", version))
213213
tmpDir, err := update.DownloadAndUnpack()
214214
if err != nil {

cmd/state/autoupdate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func autoUpdate(svc *model.SvcModel, args []string, childCmd *captain.Command, c
5353
}
5454

5555
avUpdate := updater.NewAvailableUpdate(upd.Channel, upd.Version, upd.Platform, upd.Path, upd.Sha256, "")
56-
up := updater.NewUpdateInstaller(an, avUpdate)
56+
up := updater.NewUpdateInstaller(cfg, an, avUpdate)
5757
if !up.ShouldInstall() {
5858
logging.Debug("Update is not needed")
5959
return false, nil

internal/constants/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,9 @@ const AnalyticsPixelOverrideConfig = "report.analytics.endpoint"
418418
// UpdateEndpointConfig is the config key used to determine the update endpoint to use
419419
const UpdateEndpointConfig = "update.endpoint"
420420

421+
// UpdateInfoEndpointConfig is the config key used to determine the update info endpoint to use
422+
const UpdateInfoEndpointConfig = "update.info.endpoint"
423+
421424
// NotificationsURLConfig is the config key used to determine the notifications url to use
422425
const NotificationsURLConfig = "notifications.endpoint"
423426

internal/runners/update/update.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (u *Update) Run(params *Params) error {
6565
))
6666
}
6767

68-
update := updater.NewUpdateInstaller(u.an, upd)
68+
update := updater.NewUpdateInstaller(u.cfg, u.an, upd)
6969
if !update.ShouldInstall() {
7070
logging.Debug("No update found")
7171
u.out.Print(output.Prepare(

internal/updater/checker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var (
3535
)
3636

3737
func init() {
38-
configMediator.RegisterOption(constants.UpdateEndpointConfig, configMediator.String, "")
38+
configMediator.RegisterOption(constants.UpdateInfoEndpointConfig, configMediator.String, "")
3939
}
4040

4141
type Checker struct {
@@ -87,7 +87,7 @@ func (u *Checker) infoURL(tag, desiredVersion, branchName, platform, arch string
8787
infoURL string
8888

8989
envUrl = os.Getenv("_TEST_UPDATE_INFO_URL")
90-
cfgUrl = u.cfg.GetString(constants.UpdateEndpointConfig)
90+
cfgUrl = u.cfg.GetString(constants.UpdateInfoEndpointConfig)
9191
)
9292
switch {
9393
case envUrl != "":

internal/updater/updater.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/ActiveState/cli/internal/installation/storage"
2424
"github.com/ActiveState/cli/internal/locale"
2525
"github.com/ActiveState/cli/internal/logging"
26+
configMediator "github.com/ActiveState/cli/internal/mediators/config"
2627
"github.com/ActiveState/cli/internal/multilog"
2728
"github.com/ActiveState/cli/internal/osutils"
2829
"github.com/ActiveState/cli/internal/rtutils"
@@ -34,6 +35,10 @@ const (
3435
InstallerName = "state-installer" + osutils.ExeExtension
3536
)
3637

38+
func init() {
39+
configMediator.RegisterOption(constants.UpdateEndpointConfig, configMediator.String, "")
40+
}
41+
3742
type ErrorInProgress struct{ *locale.LocalizedError }
3843

3944
var errPrivilegeMistmatch = errs.New("Privilege mismatch")
@@ -101,22 +106,40 @@ type UpdateInstaller struct {
101106

102107
// NewUpdateInstallerByOrigin returns an instance of Update. Allowing origin to
103108
// be set is useful for testing.
104-
func NewUpdateInstallerByOrigin(an analytics.Dispatcher, origin *Origin, avUpdate *AvailableUpdate) *UpdateInstaller {
105-
apiUpdateURL := constants.APIUpdateURL
106-
if url, ok := os.LookupEnv("_TEST_UPDATE_URL"); ok {
107-
apiUpdateURL = url
108-
}
109-
110-
return &UpdateInstaller{
109+
func NewUpdateInstallerByOrigin(cfg Configurable, an analytics.Dispatcher, origin *Origin, avUpdate *AvailableUpdate) *UpdateInstaller {
110+
updater := &UpdateInstaller{
111111
AvailableUpdate: avUpdate,
112112
Origin: origin,
113-
url: apiUpdateURL + "/" + avUpdate.Path,
113+
url: getAPIUpdateURL(cfg, avUpdate.Path),
114114
an: an,
115115
}
116+
117+
configMediator.AddListener(constants.UpdateEndpointConfig, func() {
118+
updater.url = getAPIUpdateURL(cfg, avUpdate.Path)
119+
})
120+
121+
return updater
122+
}
123+
124+
func NewUpdateInstaller(cfg Configurable, an analytics.Dispatcher, avUpdate *AvailableUpdate) *UpdateInstaller {
125+
return NewUpdateInstallerByOrigin(cfg, an, NewOriginDefault(), avUpdate)
116126
}
117127

118-
func NewUpdateInstaller(an analytics.Dispatcher, avUpdate *AvailableUpdate) *UpdateInstaller {
119-
return NewUpdateInstallerByOrigin(an, NewOriginDefault(), avUpdate)
128+
func getAPIUpdateURL(cfg Configurable, path string) string {
129+
var apiUpdateURL string
130+
131+
envUrl := os.Getenv("_TEST_UPDATE_URL")
132+
cfgUrl := cfg.GetString(constants.UpdateEndpointConfig)
133+
switch {
134+
case envUrl != "":
135+
apiUpdateURL = envUrl
136+
case cfgUrl != "":
137+
apiUpdateURL = cfgUrl
138+
default:
139+
apiUpdateURL = constants.APIUpdateURL
140+
}
141+
142+
return apiUpdateURL + "/" + path
120143
}
121144

122145
func (u *UpdateInstaller) ShouldInstall() bool {

internal/updater/updater_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ import (
66
"github.com/stretchr/testify/assert"
77
)
88

9+
type mockConfig struct{}
10+
11+
func (m *mockConfig) GetString(key string) string {
12+
return ""
13+
}
14+
15+
func (m *mockConfig) Set(key string, value interface{}) error {
16+
return nil
17+
}
18+
919
func newAvailableUpdate(channel, version string) *AvailableUpdate {
1020
return NewAvailableUpdate(channel, version, "platform", "path/to/zipfile.zip", "123456", "")
1121
}
@@ -45,7 +55,7 @@ func TestUpdateNotNeeded(t *testing.T) {
4555

4656
for _, tt := range tests {
4757
t.Run(tt.Name, func(t *testing.T) {
48-
upd := NewUpdateInstallerByOrigin(nil, tt.Origin, tt.AvailableUpdate)
58+
upd := NewUpdateInstallerByOrigin(&mockConfig{}, nil, tt.Origin, tt.AvailableUpdate)
4959
assert.Equal(t, tt.IsUseful, upd.ShouldInstall())
5060
})
5161
}

test/integration/update_int_test.go

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,14 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateTags() {
275275
}
276276
}
277277

278-
func (suite *UpdateIntegrationTestSuite) TestUpdateHost_SetBeforeInvocation() {
278+
func (suite *UpdateIntegrationTestSuite) TestUpdateInfoHost_SetBeforeInvocation() {
279279
suite.OnlyRunForTags(tagsuite.Update)
280280

281281
ts := e2e.New(suite.T(), false)
282282
defer ts.Close()
283283

284-
ts.SetConfig(constants.UpdateEndpointConfig, "https://test.example.com/update")
285-
suite.Assert().Equal(ts.GetConfig(constants.UpdateEndpointConfig), "https://test.example.com/update")
284+
ts.SetConfig(constants.UpdateInfoEndpointConfig, "https://test.example.com/update")
285+
suite.Assert().Equal(ts.GetConfig(constants.UpdateInfoEndpointConfig), "https://test.example.com/update")
286286

287287
cp := ts.SpawnWithOpts(
288288
e2e.OptArgs("--version"),
@@ -303,6 +303,63 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateHost_SetBeforeInvocation() {
303303
suite.Assert().Greater(correctHostCount, 0, "Log file should contain the configured API host 'test.example.com'")
304304
suite.Assert().Equal(incorrectHostCount, 0, "Log file should not contain the default API host 'platform.activestate.com'")
305305

306+
// Clean up - remove the config setting
307+
cp = ts.Spawn("config", "set", constants.UpdateInfoEndpointConfig, "")
308+
cp.Expect("Successfully")
309+
cp.ExpectExitCode(0)
310+
}
311+
312+
func (suite *UpdateIntegrationTestSuite) TestUpdateInfoHost() {
313+
suite.OnlyRunForTags(tagsuite.Update)
314+
315+
ts := e2e.New(suite.T(), false)
316+
defer ts.Close()
317+
318+
cp := ts.Spawn("config", "set", constants.UpdateInfoEndpointConfig, "https://example.com/update-info")
319+
cp.Expect("Successfully set config key")
320+
cp.ExpectExitCode(0)
321+
322+
cp = ts.SpawnWithOpts(
323+
e2e.OptArgs("update"),
324+
e2e.OptAppendEnv(suite.env(false, false)...),
325+
e2e.OptAppendEnv("VERBOSE=true"),
326+
)
327+
cp.ExpectExitCode(0)
328+
329+
output := cp.Snapshot()
330+
suite.Assert().Contains(output, "Getting update info: https://example.com/update-info/")
331+
}
332+
333+
func (suite *UpdateIntegrationTestSuite) TestUpdateHost_SetBeforeInvocation() {
334+
suite.OnlyRunForTags(tagsuite.Update)
335+
336+
ts := e2e.New(suite.T(), false)
337+
defer ts.Close()
338+
339+
ts.SetConfig(constants.UpdateInfoEndpointConfig, "https://test.example.com/update")
340+
suite.Assert().Equal(ts.GetConfig(constants.UpdateInfoEndpointConfig), "https://test.example.com/update")
341+
342+
cp := ts.SpawnWithOpts(
343+
e2e.OptArgs("update"),
344+
e2e.OptAppendEnv(suite.env(false, false)...),
345+
e2e.OptAppendEnv("VERBOSE=true"),
346+
)
347+
cp.ExpectExitCode(11) // Expect failure due to DNS resolution of fake host
348+
349+
correctHostCount := 0
350+
incorrectHostCount := 0
351+
for _, path := range ts.LogFiles() {
352+
contents := string(fileutils.ReadFileUnsafe(path))
353+
if strings.Contains(contents, "https://test.example.com/update") {
354+
correctHostCount++
355+
}
356+
if strings.Contains(contents, "https://state-tool.activestate.com/update") {
357+
incorrectHostCount++
358+
}
359+
}
360+
suite.Assert().Greater(correctHostCount, 0, "Log file should contain the configured update endpoint 'test.example.com'")
361+
suite.Assert().Equal(incorrectHostCount, 0, "Log file should not contain the default update endpoint 'state-tool.activestate.com'")
362+
306363
// Clean up - remove the config setting
307364
cp = ts.Spawn("config", "set", constants.UpdateEndpointConfig, "")
308365
cp.Expect("Successfully")
@@ -326,8 +383,19 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateHost() {
326383
)
327384
cp.ExpectExitCode(0)
328385

329-
output := cp.Snapshot()
330-
suite.Assert().Contains(output, "Getting update info: https://example.com/update/")
386+
correctHostCount := 0
387+
incorrectHostCount := 0
388+
for _, path := range ts.LogFiles() {
389+
contents := string(fileutils.ReadFileUnsafe(path))
390+
if strings.Contains(contents, "https://example.com/update") {
391+
correctHostCount++
392+
}
393+
if strings.Contains(contents, "https://state-tool.activestate.com/update") {
394+
incorrectHostCount++
395+
}
396+
}
397+
suite.Assert().Greater(correctHostCount, 0, "Log file should contain the configured update endpoint 'example.com'")
398+
suite.Assert().Equal(incorrectHostCount, 0, "Log file should not contain the default update endpoint 'state-tool.activestate.com'")
331399
}
332400

333401
func TestUpdateIntegrationTestSuite(t *testing.T) {

0 commit comments

Comments
 (0)