diff --git a/internal/aghtest/aghtest.go b/internal/aghtest/aghtest.go index 3297795a..98de9b05 100644 --- a/internal/aghtest/aghtest.go +++ b/internal/aghtest/aghtest.go @@ -4,10 +4,14 @@ package aghtest import ( "crypto/sha256" "io" + "net/http" + "net/http/httptest" "net/netip" + "net/url" "testing" "github.com/AdguardTeam/golibs/log" + "github.com/stretchr/testify/require" ) const ( @@ -51,3 +55,19 @@ func HostToIPs(host string) (ipv4, ipv6 netip.Addr) { return netip.AddrFrom4([4]byte(hash[:4])), netip.AddrFrom16([16]byte(hash[4:20])) } + +// StartHTTPServer is a helper that starts the HTTP server, which is configured +// to return data on every request, and returns the client and server URL. +func StartHTTPServer(t testing.TB, data []byte) (c *http.Client, u *url.URL) { + t.Helper() + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write(data) + })) + t.Cleanup(srv.Close) + + u, err := url.Parse(srv.URL) + require.NoError(t, err) + + return srv.Client(), u +} diff --git a/internal/home/home.go b/internal/home/home.go index 613e6429..f166e3a3 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -9,8 +9,10 @@ import ( "net" "net/http" "net/netip" + "net/url" "os" "os/signal" + "path" "path/filepath" "runtime" "sync" @@ -559,16 +561,28 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) { err = setupOpts(opts) fatalOnError(err) + execPath, err := os.Executable() + fatalOnError(errors.Annotate(err, "getting executable path: %w")) + + u := &url.URL{ + Scheme: "https", + // TODO(a.garipov): Make configurable. + Host: "static.adtidy.org", + Path: path.Join("adguardhome", version.Channel(), "version.json"), + } + upd := updater.NewUpdater(&updater.Config{ - Client: config.Filtering.HTTPClient, - Version: version.Version(), - Channel: version.Channel(), - GOARCH: runtime.GOARCH, - GOOS: runtime.GOOS, - GOARM: version.GOARM(), - GOMIPS: version.GOMIPS(), - WorkDir: Context.workDir, - ConfName: config.getConfigFilename(), + Client: config.Filtering.HTTPClient, + Version: version.Version(), + Channel: version.Channel(), + GOARCH: runtime.GOARCH, + GOOS: runtime.GOOS, + GOARM: version.GOARM(), + GOMIPS: version.GOMIPS(), + WorkDir: Context.workDir, + ConfName: config.getConfigFilename(), + ExecPath: execPath, + VersionCheckURL: u.String(), }) // TODO(e.burkov): This could be made earlier, probably as the option's diff --git a/internal/updater/check_test.go b/internal/updater/check_test.go new file mode 100644 index 00000000..e61ba443 --- /dev/null +++ b/internal/updater/check_test.go @@ -0,0 +1,148 @@ +package updater_test + +import ( + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/AdguardTeam/AdGuardHome/internal/aghalg" + "github.com/AdguardTeam/AdGuardHome/internal/aghtest" + "github.com/AdguardTeam/AdGuardHome/internal/updater" + "github.com/AdguardTeam/AdGuardHome/internal/version" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUpdater_VersionInfo(t *testing.T) { + const jsonData = `{ + "version": "v0.103.0-beta.2", + "announcement": "AdGuard Home v0.103.0-beta.2 is now available!", + "announcement_url": "https://github.com/AdguardTeam/AdGuardHome/internal/releases", + "selfupdate_min_version": "v0.0", + "download_windows_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_windows_amd64.zip", + "download_windows_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_windows_386.zip", + "download_darwin_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_darwin_amd64.zip", + "download_darwin_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_darwin_386.zip", + "download_linux_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz", + "download_linux_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_386.tar.gz", + "download_linux_arm": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz", + "download_linux_armv5": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz", + "download_linux_armv6": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz", + "download_linux_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz", + "download_linux_arm64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz", + "download_linux_mips": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz", + "download_linux_mipsle": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mipsle_softfloat.tar.gz", + "download_linux_mips64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips64_softfloat.tar.gz", + "download_linux_mips64le": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips64le_softfloat.tar.gz", + "download_freebsd_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_386.tar.gz", + "download_freebsd_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz", + "download_freebsd_arm": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz", + "download_freebsd_armv5": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv5.tar.gz", + "download_freebsd_armv6": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz", + "download_freebsd_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv7.tar.gz", + "download_freebsd_arm64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_arm64.tar.gz" +}` + + counter := 0 + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + counter++ + _, _ = w.Write([]byte(jsonData)) + })) + t.Cleanup(srv.Close) + + fakeURL, err := url.JoinPath(srv.URL, "adguardhome", version.ChannelBeta, "version.json") + require.NoError(t, err) + + u := updater.NewUpdater(&updater.Config{ + Client: srv.Client(), + Version: "v0.103.0-beta.1", + Channel: version.ChannelBeta, + GOARCH: "arm", + GOOS: "linux", + VersionCheckURL: fakeURL, + }) + + info, err := u.VersionInfo(false) + require.NoError(t, err) + + assert.Equal(t, counter, 1) + assert.Equal(t, "v0.103.0-beta.2", info.NewVersion) + assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement) + assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL) + assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate) + + t.Run("cache_check", func(t *testing.T) { + _, err = u.VersionInfo(false) + require.NoError(t, err) + + assert.Equal(t, counter, 1) + }) + + t.Run("force_check", func(t *testing.T) { + _, err = u.VersionInfo(true) + require.NoError(t, err) + + assert.Equal(t, counter, 2) + }) + + t.Run("api_fail", func(t *testing.T) { + srv.Close() + + _, err = u.VersionInfo(true) + var urlErr *url.Error + assert.ErrorAs(t, err, &urlErr) + }) +} + +func TestUpdater_VersionInfo_others(t *testing.T) { + const jsonData = `{ + "version": "v0.103.0-beta.2", + "announcement": "AdGuard Home v0.103.0-beta.2 is now available!", + "announcement_url": "https://github.com/AdguardTeam/AdGuardHome/internal/releases", + "selfupdate_min_version": "v0.0", + "download_linux_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz", + "download_linux_mips_softfloat": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz" +}` + + fakeClient, fakeURL := aghtest.StartHTTPServer(t, []byte(jsonData)) + fakeURL = fakeURL.JoinPath("adguardhome", version.ChannelBeta, "version.json") + + testCases := []struct { + name string + arch string + arm string + mips string + }{{ + name: "ARM", + arch: "arm", + arm: "7", + mips: "", + }, { + name: "MIPS", + arch: "mips", + mips: "softfloat", + arm: "", + }} + + for _, tc := range testCases { + u := updater.NewUpdater(&updater.Config{ + Client: fakeClient, + Version: "v0.103.0-beta.1", + Channel: version.ChannelBeta, + GOOS: "linux", + GOARCH: tc.arch, + GOARM: tc.arm, + GOMIPS: tc.mips, + VersionCheckURL: fakeURL.String(), + }) + + info, err := u.VersionInfo(false) + require.NoError(t, err) + + assert.Equal(t, "v0.103.0-beta.2", info.NewVersion) + assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement) + assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL) + assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate) + } +} diff --git a/internal/updater/testdata/AdGuardHome_unix.tar.gz b/internal/updater/testdata/AdGuardHome_unix.tar.gz new file mode 100644 index 00000000..611468f0 Binary files /dev/null and b/internal/updater/testdata/AdGuardHome_unix.tar.gz differ diff --git a/internal/updater/updater.go b/internal/updater/updater.go index ff76b978..7041963e 100644 --- a/internal/updater/updater.go +++ b/internal/updater/updater.go @@ -8,10 +8,8 @@ import ( "fmt" "io" "net/http" - "net/url" "os" "os/exec" - "path" "path/filepath" "strings" "sync" @@ -36,6 +34,7 @@ type Updater struct { workDir string confName string + execPath string versionCheckURL string // mu protects all fields below. @@ -74,18 +73,19 @@ type Config struct { // ConfName is the name of the current configuration file. Typically, // "AdGuardHome.yaml". ConfName string + // WorkDir is the working directory that is used for temporary files. WorkDir string + + // ExecPath is path to the executable file. + ExecPath string + + // VersionCheckURL is url to the latest version announcement. + VersionCheckURL string } // NewUpdater creates a new Updater. func NewUpdater(conf *Config) *Updater { - u := &url.URL{ - Scheme: "https", - // TODO(a.garipov): Make configurable. - Host: "static.adtidy.org", - Path: path.Join("adguardhome", conf.Channel, "version.json"), - } return &Updater{ client: conf.Client, @@ -98,7 +98,8 @@ func NewUpdater(conf *Config) *Updater { confName: conf.ConfName, workDir: conf.WorkDir, - versionCheckURL: u.String(), + execPath: conf.ExecPath, + versionCheckURL: conf.VersionCheckURL, mu: &sync.RWMutex{}, } @@ -119,12 +120,7 @@ func (u *Updater) Update(firstRun bool) (err error) { } }() - execPath, err := os.Executable() - if err != nil { - return fmt.Errorf("getting executable path: %w", err) - } - - err = u.prepare(execPath) + err = u.prepare() if err != nil { return fmt.Errorf("preparing: %w", err) } @@ -178,7 +174,7 @@ func (u *Updater) VersionCheckURL() (vcu string) { } // prepare fills all necessary fields in Updater object. -func (u *Updater) prepare(exePath string) (err error) { +func (u *Updater) prepare() (err error) { u.updateDir = filepath.Join(u.workDir, fmt.Sprintf("agh-update-%s", u.newVersion)) _, pkgNameOnly := filepath.Split(u.packageURL) @@ -194,7 +190,7 @@ func (u *Updater) prepare(exePath string) (err error) { updateExeName = "AdGuardHome.exe" } - u.backupExeName = filepath.Join(u.backupDir, filepath.Base(exePath)) + u.backupExeName = filepath.Join(u.backupDir, filepath.Base(u.execPath)) u.updateExeName = filepath.Join(u.updateDir, updateExeName) log.Debug( @@ -204,7 +200,7 @@ func (u *Updater) prepare(exePath string) (err error) { u.packageURL, ) - u.currentExeName = exePath + u.currentExeName = u.execPath _, err = os.Stat(u.currentExeName) if err != nil { return fmt.Errorf("checking %q: %w", u.currentExeName, err) diff --git a/internal/updater/updater_internal_test.go b/internal/updater/updater_internal_test.go new file mode 100644 index 00000000..e233db3d --- /dev/null +++ b/internal/updater/updater_internal_test.go @@ -0,0 +1,107 @@ +package updater + +import ( + "os" + "path/filepath" + "testing" + + "github.com/AdguardTeam/AdGuardHome/internal/aghtest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUpdater_internal(t *testing.T) { + wd := t.TempDir() + + exePathUnix := filepath.Join(wd, "AdGuardHome.exe") + exePathWindows := filepath.Join(wd, "AdGuardHome") + yamlPath := filepath.Join(wd, "AdGuardHome.yaml") + readmePath := filepath.Join(wd, "README.md") + licensePath := filepath.Join(wd, "LICENSE.txt") + + require.NoError(t, os.WriteFile(exePathUnix, []byte("AdGuardHome.exe"), 0o755)) + require.NoError(t, os.WriteFile(exePathWindows, []byte("AdGuardHome"), 0o755)) + require.NoError(t, os.WriteFile(yamlPath, []byte("AdGuardHome.yaml"), 0o644)) + require.NoError(t, os.WriteFile(readmePath, []byte("README.md"), 0o644)) + require.NoError(t, os.WriteFile(licensePath, []byte("LICENSE.txt"), 0o644)) + + testCases := []struct { + name string + exeName string + os string + archiveName string + }{{ + name: "unix", + os: "linux", + exeName: "AdGuardHome", + archiveName: "AdGuardHome.tar.gz", + }, { + name: "windows", + os: "windows", + exeName: "AdGuardHome.exe", + archiveName: "AdGuardHome.zip", + }} + + for _, tc := range testCases { + exePath := filepath.Join(wd, tc.exeName) + + // start server for returning package file + pkgData, err := os.ReadFile(filepath.Join("testdata", tc.archiveName)) + require.NoError(t, err) + + fakeClient, fakeURL := aghtest.StartHTTPServer(t, pkgData) + fakeURL = fakeURL.JoinPath(tc.archiveName) + + u := NewUpdater(&Config{ + Client: fakeClient, + GOOS: tc.os, + Version: "v0.103.0", + ExecPath: exePath, + WorkDir: wd, + ConfName: yamlPath, + }) + + u.newVersion = "v0.103.1" + u.packageURL = fakeURL.String() + + require.NoError(t, u.prepare()) + require.NoError(t, u.downloadPackageFile()) + require.NoError(t, u.unpack()) + require.NoError(t, u.backup(false)) + require.NoError(t, u.replace()) + + u.clean() + + // check backup files + d, err := os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.yaml")) + require.NoError(t, err) + + assert.Equal(t, "AdGuardHome.yaml", string(d)) + + d, err = os.ReadFile(filepath.Join(wd, "agh-backup", tc.exeName)) + require.NoError(t, err) + + assert.Equal(t, tc.exeName, string(d)) + + // check updated files + d, err = os.ReadFile(exePath) + require.NoError(t, err) + + assert.Equal(t, "1", string(d)) + + d, err = os.ReadFile(readmePath) + require.NoError(t, err) + + assert.Equal(t, "2", string(d)) + + d, err = os.ReadFile(licensePath) + require.NoError(t, err) + + assert.Equal(t, "3", string(d)) + + d, err = os.ReadFile(yamlPath) + require.NoError(t, err) + + assert.Equal(t, "AdGuardHome.yaml", string(d)) + } +} diff --git a/internal/updater/updater_test.go b/internal/updater/updater_test.go index af9093cc..4af567c0 100644 --- a/internal/updater/updater_test.go +++ b/internal/updater/updater_test.go @@ -1,105 +1,38 @@ -package updater +package updater_test import ( - "net" + "fmt" "net/http" + "net/http/httptest" "net/url" "os" "path" "path/filepath" - "strconv" + "runtime" "testing" - "github.com/AdguardTeam/AdGuardHome/internal/aghalg" + "github.com/AdguardTeam/AdGuardHome/internal/updater" "github.com/AdguardTeam/AdGuardHome/internal/version" "github.com/AdguardTeam/golibs/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// TODO(a.garipov): Rewrite these tests. - func TestMain(m *testing.M) { testutil.DiscardLogOutput(m) } -func startHTTPServer(data string) (l net.Listener, portStr string) { - mux := http.NewServeMux() - mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { - _, _ = w.Write([]byte(data)) - }) - - listener, err := net.Listen("tcp", ":0") - if err != nil { - panic(err) - } - - go func() { _ = http.Serve(listener, mux) }() - return listener, strconv.FormatUint(uint64(listener.Addr().(*net.TCPAddr).Port), 10) -} - -func TestUpdateGetVersion(t *testing.T) { +func TestUpdater_Update(t *testing.T) { const jsonData = `{ "version": "v0.103.0-beta.2", "announcement": "AdGuard Home v0.103.0-beta.2 is now available!", "announcement_url": "https://github.com/AdguardTeam/AdGuardHome/internal/releases", "selfupdate_min_version": "v0.0", - "download_windows_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_windows_amd64.zip", - "download_windows_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_windows_386.zip", - "download_darwin_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_darwin_amd64.zip", - "download_darwin_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_darwin_386.zip", - "download_linux_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz", - "download_linux_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_386.tar.gz", - "download_linux_arm": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz", - "download_linux_armv5": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz", - "download_linux_armv6": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz", - "download_linux_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz", - "download_linux_arm64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz", - "download_linux_mips": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz", - "download_linux_mipsle": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mipsle_softfloat.tar.gz", - "download_linux_mips64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips64_softfloat.tar.gz", - "download_linux_mips64le": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips64le_softfloat.tar.gz", - "download_freebsd_386": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_386.tar.gz", - "download_freebsd_amd64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz", - "download_freebsd_arm": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz", - "download_freebsd_armv5": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv5.tar.gz", - "download_freebsd_armv6": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz", - "download_freebsd_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_armv7.tar.gz", - "download_freebsd_arm64": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_freebsd_arm64.tar.gz" + "download_linux_amd64": "%s" }` - l, lport := startHTTPServer(jsonData) - testutil.CleanupAndRequireSuccess(t, l.Close) + const packagePath = "/AdGuardHome.tar.gz" - u := NewUpdater(&Config{ - Client: &http.Client{}, - Version: "v0.103.0-beta.1", - Channel: version.ChannelBeta, - GOARCH: "arm", - GOOS: "linux", - }) - - fakeURL := &url.URL{ - Scheme: "http", - Host: net.JoinHostPort("127.0.0.1", lport), - Path: path.Join("adguardhome", version.ChannelBeta, "version.json"), - } - u.versionCheckURL = fakeURL.String() - - info, err := u.VersionInfo(false) - require.NoError(t, err) - - assert.Equal(t, "v0.103.0-beta.2", info.NewVersion) - assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement) - assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL) - assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate) - - // check cached - _, err = u.VersionInfo(false) - require.NoError(t, err) -} - -func TestUpdate(t *testing.T) { wd := t.TempDir() exePath := filepath.Join(wd, "AdGuardHome") @@ -112,55 +45,61 @@ func TestUpdate(t *testing.T) { require.NoError(t, os.WriteFile(readmePath, []byte("README.md"), 0o644)) require.NoError(t, os.WriteFile(licensePath, []byte("LICENSE.txt"), 0o644)) - // start server for returning package file - pkgData, err := os.ReadFile("testdata/AdGuardHome.tar.gz") + pkgData, err := os.ReadFile("testdata/AdGuardHome_unix.tar.gz") require.NoError(t, err) - l, lport := startHTTPServer(string(pkgData)) - testutil.CleanupAndRequireSuccess(t, l.Close) - - u := NewUpdater(&Config{ - Client: &http.Client{}, - Version: "v0.103.0", + mux := http.NewServeMux() + mux.HandleFunc(packagePath, func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write(pkgData) }) - fakeURL := &url.URL{ - Scheme: "http", - Host: net.JoinHostPort("127.0.0.1", lport), - Path: "AdGuardHome.tar.gz", - } + versionPath := path.Join("/adguardhome", version.ChannelBeta, "version.json") + mux.HandleFunc(versionPath, func(w http.ResponseWriter, r *http.Request) { + var u string + u, err = url.JoinPath("http://", r.Host, packagePath) + require.NoError(t, err) - u.workDir = wd - u.confName = yamlPath - u.newVersion = "v0.103.1" - u.packageURL = fakeURL.String() + _, _ = fmt.Fprintf(w, jsonData, u) + }) - require.NoError(t, u.prepare(exePath)) - require.NoError(t, u.downloadPackageFile()) - require.NoError(t, u.unpack()) - // require.NoError(t, u.check()) - require.NoError(t, u.backup(false)) - require.NoError(t, u.replace()) + srv := httptest.NewServer(mux) + t.Cleanup(srv.Close) - u.clean() + versionCheckURL, err := url.JoinPath(srv.URL, versionPath) + require.NoError(t, err) + + u := updater.NewUpdater(&updater.Config{ + Client: srv.Client(), + GOARCH: "amd64", + GOOS: "linux", + Version: "v0.103.0", + ConfName: yamlPath, + WorkDir: wd, + ExecPath: exePath, + VersionCheckURL: versionCheckURL, + }) + + _, err = u.VersionInfo(false) + require.NoError(t, err) + + err = u.Update(true) + require.NoError(t, err) // check backup files - d, err := os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.yaml")) + d, err := os.ReadFile(filepath.Join(wd, "agh-backup", "LICENSE.txt")) require.NoError(t, err) - assert.Equal(t, "AdGuardHome.yaml", string(d)) + assert.Equal(t, "LICENSE.txt", string(d)) - d, err = os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome")) + d, err = os.ReadFile(filepath.Join(wd, "agh-backup", "README.md")) require.NoError(t, err) - assert.Equal(t, "AdGuardHome", string(d)) + assert.Equal(t, "README.md", string(d)) // check updated files - d, err = os.ReadFile(exePath) + _, err = os.Stat(exePath) require.NoError(t, err) - assert.Equal(t, "1", string(d)) - d, err = os.ReadFile(readmePath) require.NoError(t, err) @@ -175,157 +114,22 @@ func TestUpdate(t *testing.T) { require.NoError(t, err) assert.Equal(t, "AdGuardHome.yaml", string(d)) -} -func TestUpdateWindows(t *testing.T) { - wd := t.TempDir() + t.Run("config_check", func(t *testing.T) { + // TODO(s.chzhen): Test on Windows also. + if runtime.GOOS == "windows" { + t.Skip("skipping config check test on windows") + } - exePath := filepath.Join(wd, "AdGuardHome.exe") - yamlPath := filepath.Join(wd, "AdGuardHome.yaml") - readmePath := filepath.Join(wd, "README.md") - licensePath := filepath.Join(wd, "LICENSE.txt") - - require.NoError(t, os.WriteFile(exePath, []byte("AdGuardHome.exe"), 0o755)) - require.NoError(t, os.WriteFile(yamlPath, []byte("AdGuardHome.yaml"), 0o644)) - require.NoError(t, os.WriteFile(readmePath, []byte("README.md"), 0o644)) - require.NoError(t, os.WriteFile(licensePath, []byte("LICENSE.txt"), 0o644)) - - // start server for returning package file - pkgData, err := os.ReadFile("testdata/AdGuardHome.zip") - require.NoError(t, err) - - l, lport := startHTTPServer(string(pkgData)) - testutil.CleanupAndRequireSuccess(t, l.Close) - - u := NewUpdater(&Config{ - Client: &http.Client{}, - GOOS: "windows", - Version: "v0.103.0", + err = u.Update(false) + assert.NoError(t, err) }) - fakeURL := &url.URL{ - Scheme: "http", - Host: net.JoinHostPort("127.0.0.1", lport), - Path: "AdGuardHome.zip", - } + t.Run("api_fail", func(t *testing.T) { + srv.Close() - u.workDir = wd - u.confName = yamlPath - u.newVersion = "v0.103.1" - u.packageURL = fakeURL.String() - - require.NoError(t, u.prepare(exePath)) - require.NoError(t, u.downloadPackageFile()) - require.NoError(t, u.unpack()) - // assert.Nil(t, u.check()) - require.NoError(t, u.backup(false)) - require.NoError(t, u.replace()) - - u.clean() - - // check backup files - d, err := os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.yaml")) - require.NoError(t, err) - - assert.Equal(t, "AdGuardHome.yaml", string(d)) - - d, err = os.ReadFile(filepath.Join(wd, "agh-backup", "AdGuardHome.exe")) - require.NoError(t, err) - - assert.Equal(t, "AdGuardHome.exe", string(d)) - - // check updated files - d, err = os.ReadFile(exePath) - require.NoError(t, err) - - assert.Equal(t, "1", string(d)) - - d, err = os.ReadFile(readmePath) - require.NoError(t, err) - - assert.Equal(t, "2", string(d)) - - d, err = os.ReadFile(licensePath) - require.NoError(t, err) - - assert.Equal(t, "3", string(d)) - - d, err = os.ReadFile(yamlPath) - require.NoError(t, err) - - assert.Equal(t, "AdGuardHome.yaml", string(d)) -} - -func TestUpdater_VersionInto_ARM(t *testing.T) { - const jsonData = `{ - "version": "v0.103.0-beta.2", - "announcement": "AdGuard Home v0.103.0-beta.2 is now available!", - "announcement_url": "https://github.com/AdguardTeam/AdGuardHome/internal/releases", - "selfupdate_min_version": "v0.0", - "download_linux_armv7": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz" -}` - - l, lport := startHTTPServer(jsonData) - testutil.CleanupAndRequireSuccess(t, l.Close) - - u := NewUpdater(&Config{ - Client: &http.Client{}, - Version: "v0.103.0-beta.1", - Channel: version.ChannelBeta, - GOARCH: "arm", - GOOS: "linux", - GOARM: "7", + err = u.Update(true) + var urlErr *url.Error + assert.ErrorAs(t, err, &urlErr) }) - - fakeURL := &url.URL{ - Scheme: "http", - Host: net.JoinHostPort("127.0.0.1", lport), - Path: path.Join("adguardhome", version.ChannelBeta, "version.json"), - } - u.versionCheckURL = fakeURL.String() - - info, err := u.VersionInfo(false) - require.NoError(t, err) - - assert.Equal(t, "v0.103.0-beta.2", info.NewVersion) - assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement) - assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL) - assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate) -} - -func TestUpdater_VersionInto_MIPS(t *testing.T) { - const jsonData = `{ - "version": "v0.103.0-beta.2", - "announcement": "AdGuard Home v0.103.0-beta.2 is now available!", - "announcement_url": "https://github.com/AdguardTeam/AdGuardHome/internal/releases", - "selfupdate_min_version": "v0.0", - "download_linux_mips_softfloat": "https://static.adtidy.org/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz" -}` - - l, lport := startHTTPServer(jsonData) - testutil.CleanupAndRequireSuccess(t, l.Close) - - u := NewUpdater(&Config{ - Client: &http.Client{}, - Version: "v0.103.0-beta.1", - Channel: version.ChannelBeta, - GOARCH: "mips", - GOOS: "linux", - GOMIPS: "softfloat", - }) - - fakeURL := &url.URL{ - Scheme: "http", - Host: net.JoinHostPort("127.0.0.1", lport), - Path: path.Join("adguardhome", version.ChannelBeta, "version.json"), - } - u.versionCheckURL = fakeURL.String() - - info, err := u.VersionInfo(false) - require.NoError(t, err) - - assert.Equal(t, "v0.103.0-beta.2", info.NewVersion) - assert.Equal(t, "AdGuard Home v0.103.0-beta.2 is now available!", info.Announcement) - assert.Equal(t, "https://github.com/AdguardTeam/AdGuardHome/internal/releases", info.AnnouncementURL) - assert.Equal(t, aghalg.NBTrue, info.CanAutoUpdate) }