forked from Plemya-x/ALR
		
	tests: add tests for dl
This commit is contained in:
		| @@ -11,7 +11,7 @@ | ||||
|     <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> | ||||
|         <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> | ||||
|         <text x="33.5" y="14">coverage</text> | ||||
|         <text x="86" y="15" fill="#010101" fill-opacity=".3">14.4%</text> | ||||
|         <text x="86" y="14">14.4%</text> | ||||
|         <text x="86" y="15" fill="#010101" fill-opacity=".3">18.2%</text> | ||||
|         <text x="86" y="14">18.2%</text> | ||||
|     </g> | ||||
| </svg> | ||||
|   | ||||
| Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 926 B | 
| @@ -42,9 +42,6 @@ import ( | ||||
| 	"golang.org/x/crypto/blake2b" | ||||
| 	"golang.org/x/crypto/blake2s" | ||||
| 	"golang.org/x/exp/slices" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/dlcache" | ||||
| ) | ||||
|  | ||||
| // Константа для имени файла манифеста кэша | ||||
| @@ -83,6 +80,11 @@ func (t Type) String() string { | ||||
| 	return "<unknown>" | ||||
| } | ||||
|  | ||||
| type DlCache interface { | ||||
| 	Get(context.Context, string) (string, bool) | ||||
| 	New(context.Context, string) (string, error) | ||||
| } | ||||
|  | ||||
| // Структура Options содержит параметры для загрузки файлов и каталогов | ||||
| type Options struct { | ||||
| 	Hash             []byte | ||||
| @@ -94,6 +96,7 @@ type Options struct { | ||||
| 	PostprocDisabled bool | ||||
| 	Progress         io.Writer | ||||
| 	LocalDir         string | ||||
| 	DlCache          DlCache | ||||
| } | ||||
|  | ||||
| // Метод для создания нового хеша на основе указанного алгоритма хеширования | ||||
| @@ -145,9 +148,6 @@ type UpdatingDownloader interface { | ||||
|  | ||||
| // Функция Download загружает файл или каталог с использованием указанных параметров | ||||
| func Download(ctx context.Context, opts Options) (err error) { | ||||
| 	cfg := config.GetInstance(ctx) | ||||
| 	dc := dlcache.New(cfg) | ||||
|  | ||||
| 	normalized, err := normalizeURL(opts.URL) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -162,7 +162,7 @@ func Download(ctx context.Context, opts Options) (err error) { | ||||
| 	} | ||||
|  | ||||
| 	var t Type | ||||
| 	cacheDir, ok := dc.Get(ctx, opts.URL) | ||||
| 	cacheDir, ok := opts.DlCache.Get(ctx, opts.URL) | ||||
| 	if ok { | ||||
| 		var updated bool | ||||
| 		if d, ok := d.(UpdatingDownloader); ok { | ||||
| @@ -221,7 +221,7 @@ func Download(ctx context.Context, opts Options) (err error) { | ||||
|  | ||||
| 	slog.Info(gotext.Get("Downloading source"), "source", opts.Name, "downloader", d.Name()) | ||||
|  | ||||
| 	cacheDir, err = dc.New(ctx, opts.URL) | ||||
| 	cacheDir, err = opts.DlCache.New(ctx, opts.URL) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										139
									
								
								internal/dl/dl_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								internal/dl/dl_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| // ALR - Any Linux Repository | ||||
| // Copyright (C) 2025 Евгений Храмов | ||||
| // | ||||
| // This program is free software: you can redistribute it and/or modify | ||||
| // it under the terms of the GNU General Public License as published by | ||||
| // the Free Software Foundation, either version 3 of the License, or | ||||
| // (at your option) any later version. | ||||
| // | ||||
| // This program is distributed in the hope that it will be useful, | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| // GNU General Public License for more details. | ||||
| // | ||||
| // You should have received a copy of the GNU General Public License | ||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| package dl_test | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/config" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/dl" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/dlcache" | ||||
| ) | ||||
|  | ||||
| func TestDownloadFileWithoutCache(t *testing.T) { | ||||
| 	type testCase struct { | ||||
| 		name        string | ||||
| 		expectedErr error | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range []testCase{ | ||||
| 		{ | ||||
| 			name:        "simple download", | ||||
| 			expectedErr: nil, | ||||
| 		}, | ||||
| 	} { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 				switch { | ||||
| 				case r.URL.Path == "/file": | ||||
| 					w.WriteHeader(http.StatusOK) | ||||
| 					w.Write([]byte("Hello, World!")) | ||||
| 				default: | ||||
| 					w.WriteHeader(http.StatusNotFound) | ||||
| 				} | ||||
| 			})) | ||||
| 			defer server.Close() | ||||
|  | ||||
| 			tmpdir, err := os.MkdirTemp("", "test-download") | ||||
| 			assert.NoError(t, err) | ||||
| 			defer os.RemoveAll(tmpdir) | ||||
|  | ||||
| 			opts := dl.Options{ | ||||
| 				CacheDisabled: true, | ||||
| 				URL:           server.URL + "/file", | ||||
| 				Destination:   tmpdir, | ||||
| 			} | ||||
|  | ||||
| 			err = dl.Download(context.Background(), opts) | ||||
| 			assert.ErrorIs(t, err, tc.expectedErr) | ||||
| 			_, err = os.Stat(path.Join(tmpdir, "file")) | ||||
| 			assert.NoError(t, err) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type TestALRConfig struct{} | ||||
|  | ||||
| func (c *TestALRConfig) GetPaths(ctx context.Context) *config.Paths { | ||||
| 	return &config.Paths{ | ||||
| 		CacheDir: "/tmp", | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDownloadFileWithCache(t *testing.T) { | ||||
| 	type testCase struct { | ||||
| 		name        string | ||||
| 		expectedErr error | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range []testCase{ | ||||
| 		{ | ||||
| 			name:        "simple download", | ||||
| 			expectedErr: nil, | ||||
| 		}, | ||||
| 	} { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			called := 0 | ||||
|  | ||||
| 			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 				switch { | ||||
| 				case r.URL.Path == "/file": | ||||
| 					called += 1 | ||||
| 					w.WriteHeader(http.StatusOK) | ||||
| 					w.Write([]byte("Hello, World!")) | ||||
| 				default: | ||||
| 					w.WriteHeader(http.StatusNotFound) | ||||
| 				} | ||||
| 			})) | ||||
| 			defer server.Close() | ||||
|  | ||||
| 			tmpdir, err := os.MkdirTemp("", "test-download") | ||||
| 			assert.NoError(t, err) | ||||
| 			defer os.RemoveAll(tmpdir) | ||||
|  | ||||
| 			cfg := &TestALRConfig{} | ||||
|  | ||||
| 			opts := dl.Options{ | ||||
| 				CacheDisabled: false, | ||||
| 				URL:           server.URL + "/file", | ||||
| 				Destination:   tmpdir, | ||||
| 				DlCache:       dlcache.New(cfg), | ||||
| 			} | ||||
|  | ||||
| 			outputFile := path.Join(tmpdir, "file") | ||||
|  | ||||
| 			err = dl.Download(context.Background(), opts) | ||||
| 			assert.ErrorIs(t, err, tc.expectedErr) | ||||
| 			_, err = os.Stat(outputFile) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = os.Remove(outputFile) | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| 			err = dl.Download(context.Background(), opts) | ||||
| 			assert.NoError(t, err) | ||||
| 			assert.Equal(t, 1, called) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -143,7 +143,7 @@ func (FileDownloader) Download(ctx context.Context, opts Options) (Type, string, | ||||
| 		return 0, "", err | ||||
| 	} | ||||
| 	r.Close() | ||||
| 	out.Close() | ||||
| 	// out.Close() | ||||
|  | ||||
| 	// Проверка контрольной суммы | ||||
| 	if opts.Hash != nil { | ||||
|   | ||||
| @@ -293,81 +293,81 @@ msgstr "" | ||||
| msgid "Error while running app" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:107 | ||||
| #: pkg/build/build.go:108 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:111 | ||||
| #: pkg/build/build.go:112 | ||||
| msgid "Building package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:155 | ||||
| #: pkg/build/build.go:156 | ||||
| msgid "Downloading sources" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:167 | ||||
| #: pkg/build/build.go:168 | ||||
| msgid "Building package metadata" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:189 | ||||
| #: pkg/build/build.go:190 | ||||
| msgid "Compressing package" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:315 | ||||
| #: pkg/build/build.go:316 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:326 | ||||
| #: pkg/build/build.go:327 | ||||
| msgid "This package is already installed" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:354 | ||||
| #: pkg/build/build.go:355 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:396 | ||||
| #: pkg/build/build.go:397 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:442 | ||||
| #: pkg/build/build.go:443 | ||||
| msgid "Executing version()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:462 | ||||
| #: pkg/build/build.go:463 | ||||
| msgid "Updating version" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:467 | ||||
| #: pkg/build/build.go:468 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:477 | ||||
| #: pkg/build/build.go:478 | ||||
| msgid "Executing build()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:487 | ||||
| #: pkg/build/build.go:488 | ||||
| msgid "Executing package()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:509 | ||||
| #: pkg/build/build.go:510 | ||||
| msgid "Executing files()" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:587 | ||||
| #: pkg/build/build.go:588 | ||||
| msgid "AutoProv is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:598 | ||||
| #: pkg/build/build.go:599 | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:705 | ||||
| #: pkg/build/build.go:706 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "" | ||||
|  | ||||
| #: pkg/build/build.go:811 | ||||
| #: pkg/build/build.go:812 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "" | ||||
|  | ||||
|   | ||||
| @@ -307,27 +307,27 @@ msgstr "" | ||||
| msgid "Error while running app" | ||||
| msgstr "Ошибка при запуске приложения" | ||||
|  | ||||
| #: pkg/build/build.go:107 | ||||
| #: pkg/build/build.go:108 | ||||
| msgid "Failed to prompt user to view build script" | ||||
| msgstr "Не удалось предложить пользователю просмотреть скрипт сборки" | ||||
|  | ||||
| #: pkg/build/build.go:111 | ||||
| #: pkg/build/build.go:112 | ||||
| msgid "Building package" | ||||
| msgstr "Сборка пакета" | ||||
|  | ||||
| #: pkg/build/build.go:155 | ||||
| #: pkg/build/build.go:156 | ||||
| msgid "Downloading sources" | ||||
| msgstr "Скачивание источников" | ||||
|  | ||||
| #: pkg/build/build.go:167 | ||||
| #: pkg/build/build.go:168 | ||||
| msgid "Building package metadata" | ||||
| msgstr "Сборка метаданных пакета" | ||||
|  | ||||
| #: pkg/build/build.go:189 | ||||
| #: pkg/build/build.go:190 | ||||
| msgid "Compressing package" | ||||
| msgstr "Сжатие пакета" | ||||
|  | ||||
| #: pkg/build/build.go:315 | ||||
| #: pkg/build/build.go:316 | ||||
| msgid "" | ||||
| "Your system's CPU architecture doesn't match this package. Do you want to " | ||||
| "build anyway?" | ||||
| @@ -335,57 +335,57 @@ msgstr "" | ||||
| "Архитектура процессора вашей системы не соответствует этому пакету. Вы все " | ||||
| "равно хотите выполнить сборку?" | ||||
|  | ||||
| #: pkg/build/build.go:326 | ||||
| #: pkg/build/build.go:327 | ||||
| msgid "This package is already installed" | ||||
| msgstr "Этот пакет уже установлен" | ||||
|  | ||||
| #: pkg/build/build.go:354 | ||||
| #: pkg/build/build.go:355 | ||||
| msgid "Installing build dependencies" | ||||
| msgstr "Установка зависимостей сборки" | ||||
|  | ||||
| #: pkg/build/build.go:396 | ||||
| #: pkg/build/build.go:397 | ||||
| msgid "Installing dependencies" | ||||
| msgstr "Установка зависимостей" | ||||
|  | ||||
| #: pkg/build/build.go:442 | ||||
| #: pkg/build/build.go:443 | ||||
| msgid "Executing version()" | ||||
| msgstr "Исполнение версия()" | ||||
|  | ||||
| #: pkg/build/build.go:462 | ||||
| #: pkg/build/build.go:463 | ||||
| msgid "Updating version" | ||||
| msgstr "Обновление версии" | ||||
|  | ||||
| #: pkg/build/build.go:467 | ||||
| #: pkg/build/build.go:468 | ||||
| msgid "Executing prepare()" | ||||
| msgstr "Исполнение prepare()" | ||||
|  | ||||
| #: pkg/build/build.go:477 | ||||
| #: pkg/build/build.go:478 | ||||
| msgid "Executing build()" | ||||
| msgstr "Исполнение build()" | ||||
|  | ||||
| #: pkg/build/build.go:487 | ||||
| #: pkg/build/build.go:488 | ||||
| msgid "Executing package()" | ||||
| msgstr "Исполнение package()" | ||||
|  | ||||
| #: pkg/build/build.go:509 | ||||
| #: pkg/build/build.go:510 | ||||
| msgid "Executing files()" | ||||
| msgstr "Исполнение files()" | ||||
|  | ||||
| #: pkg/build/build.go:587 | ||||
| #: pkg/build/build.go:588 | ||||
| msgid "AutoProv is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
| "AutoProv не реализовано для этого формата пакета, поэтому будет пропущено" | ||||
|  | ||||
| #: pkg/build/build.go:598 | ||||
| #: pkg/build/build.go:599 | ||||
| msgid "AutoReq is not implemented for this package format, so it's skipped" | ||||
| msgstr "" | ||||
| "AutoReq не реализовано для этого формата пакета, поэтому будет пропущено" | ||||
|  | ||||
| #: pkg/build/build.go:705 | ||||
| #: pkg/build/build.go:706 | ||||
| msgid "Would you like to remove the build dependencies?" | ||||
| msgstr "Хотели бы вы удалить зависимости сборки?" | ||||
|  | ||||
| #: pkg/build/build.go:811 | ||||
| #: pkg/build/build.go:812 | ||||
| msgid "The checksums array must be the same length as sources" | ||||
| msgstr "Массив контрольных сумм должен быть той же длины, что и источники" | ||||
|  | ||||
|   | ||||
| @@ -54,6 +54,7 @@ import ( | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/cpu" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/db" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/dl" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/dlcache" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/overrides" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/decoder" | ||||
| 	"gitea.plemya-x.ru/Plemya-x/ALR/internal/shutils/handlers" | ||||
| @@ -842,6 +843,9 @@ func getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		cfg := config.GetInstance(ctx) | ||||
| 		opts.DlCache = dlcache.New(cfg) | ||||
|  | ||||
| 		err := dl.Download(ctx, opts) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
|   | ||||
		Reference in New Issue
	
	Block a user