diff --git a/db_test.go b/db_test.go new file mode 100644 index 0000000..6611778 --- /dev/null +++ b/db_test.go @@ -0,0 +1,56 @@ +package pic + +import ( + "fmt" + "os" + "reflect" + "testing" + + _ "github.com/go-sql-driver/mysql" + "github.com/jmoiron/sqlx" +) + +// Это скорее интеграционное тестированиеЮ чем модульное +// Сначала создадим тестовую БД - test-sea аналог боевой + +// Выполняется один раз при прогоне +func TextMain(m *testing.M) { + db = createTestDB() + os.Exit(m.Run()) +} + +func createTestDB() *sqlx.DB { + db, err := sqlx.Open("mysql", "itman:X753951x@(xigmanas:3306)") + if err != nil { + fmt.Printf("не удалось полключиться к БД: %v\n", err) + os.Exit(0) + } + return db + +} +func Test_getAlbum(t *testing.T) { + type args struct { + db *sqlx.DB + name string + } + tests := []struct { + name string + args args + want []Picture + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getAlbum(tt.args.db, tt.args.name) + if (err != nil) != tt.wantErr { + t.Errorf("getAlbum() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getAlbum() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/picture.go b/picture.go index 0798e61..69865f3 100644 --- a/picture.go +++ b/picture.go @@ -3,6 +3,8 @@ package pic import ( "fmt" "io/ioutil" + "log" + "os" "regexp" "strings" @@ -68,9 +70,12 @@ type WebpFile struct { height string } -// конвертация из .gif в .webp с изменением размеров файла -// filename - исходный файл gif -func convert(filename string) (WebpFile, error) { +// конвертация из .gif в .webp с изменением размера файла +// с использованием программы ffmpeg. +// filename - исходный файл gif (полный путь) +// Возвращает описание выходного файла WebpFile +// Выходной файл находится рядом с исходным +func convertFile(filename string) (WebpFile, error) { webpfile := WebpFile{} cmd, webp, err := cmdFfmpeg(filename) @@ -100,6 +105,32 @@ func convert(filename string) (WebpFile, error) { return webpfile, nil } +// Экспорт функции конвертации +func Convert(filename string) error { + webp, err := convertFile(filename) + if err != nil { + return err + } + + log.Printf("[%sx%s] %s\n", webp.width, webp.height, webp.filename) + + // все сделано, удалим исходный и выходной файл + if err := deleteFile(filename); err != nil { + return err + } + + if err := deleteFile(webp.filename); err != nil { + return err + } + + return nil +} + +func deleteFile(filename string) error { + err := os.Remove(filename) + return err +} + // получает размер файла из вывода команды ffmpeg // если пустая строка - бросаем панику func getSize(out string) (string, string) { diff --git a/picture_test.go b/picture_test.go index 74247b1..73ea4ff 100644 --- a/picture_test.go +++ b/picture_test.go @@ -58,22 +58,35 @@ func TestGetSize(t *testing.T) { assert.Equal(t, h, "1980", "должны быть 1980") } -func TestConvert(t *testing.T) { +func TestConvertFile(t *testing.T) { // предварительно скопируем тестовый файл во временный каталог tmpgif := "test.gif" require.FileExists(t, tmpgif) + + // создадим временный каталог tmpdir := t.TempDir() filename := filepath.Join(tmpdir, tmpgif) + // скопируем исходный файл в этот каталог err := copyFile(tmpgif, filename) require.NoError(t, err) require.FileExists(t, filename) - webp, err := convert(filename) + // собственно конвертация + webp, err := convertFile(filename) assert.NoError(t, err) require.FileExists(t, webp.filename) // скопируем обратно, что бы посмотреть, что получилось - err = copyFile(webp.filename, "d:/projects/pic/test.webp") + // err = copyFile(webp.filename, "d:/projects/pic/test.webp") + // assert.NoError(t, err) +} + +func TestConvert(t *testing.T) { + // проверяем, что после конвертации файлы удаляются + tmpgif := "test.gif" + require.FileExists(t, tmpgif) + + err := Convert(tmpgif) assert.NoError(t, err) } diff --git a/seadb.go b/seadb.go index 4456cd5..21c6368 100644 --- a/seadb.go +++ b/seadb.go @@ -1,6 +1,8 @@ package pic import ( + "fmt" + "github.com/jmoiron/sqlx" ) @@ -10,6 +12,9 @@ type SeaDB struct { } func NewSeaDB(db *sqlx.DB) (*SeaDB, error) { + if db == nil { + return nil, fmt.Errorf("db = nil") + } seadb := SeaDB{db: db} return &seadb, nil } @@ -28,8 +33,6 @@ func (sea *SeaDB) SmallGifs() ([]string, error) { and del = 0 and filemeta.converted = 0 and pic.width < 400 - LIMIT - 10; ` var urls []string err := sea.db.Select(&urls, cmd) diff --git a/seadb_test.go b/seadb_test.go index fe2406b..35cf59d 100644 --- a/seadb_test.go +++ b/seadb_test.go @@ -3,7 +3,6 @@ package pic import ( "os" "path/filepath" - "strings" "testing" "github.com/jmoiron/sqlx" @@ -11,49 +10,56 @@ import ( "github.com/stretchr/testify/require" ) -var db = openDB() +var db *sqlx.DB func openDB() *sqlx.DB { - db, err := sqlx.Open("mysql", "itman:X753951x@(xigmanas:3306)/sea") + db, err := sqlx.Open("mysql", "itman:X753951x@(xigmanas:3306)/sea-test") if err != nil { panic(err) } return db } -// создадим временный каталог для тестирования +// Первоначальная установка окружения func TestMain(m *testing.M) { - os.RemoveAll("test") - os.Mkdir("test", 0666) + // Каталог test должен присутствовать и в нем должны находиться: + // sea-test.sql - скрипт для создания тестовой БД и заполнения ее тестовыми данными (mock) + // test.gif - тестовый gif (mock) + + //os.RemoveAll("test") + //os.Mkdir("test", 0666) + db = openDB() os.Exit(m.Run()) } func TestGetSmallGifs(t *testing.T) { + // db открыта на глобальном уровне seadb, err := NewSeaDB(db) // если ошибка - дальнейшая проверка бессмыслена require.NoError(t, err) urls, err := seadb.SmallGifs() assert.Nil(t, err) - assert.Equal(t, len(urls), 10, "должны получить ровно 10 записей") - // теперь проверяем правильность формата url - // должны быть в форме: http://192.168.0.105:9091/4,530f8ea86e3e.gif - for _, u := range urls { - assert.Equal(t, strings.HasPrefix(u, "http://192.168.0.105:9091/"), true, "должен начинаться с http://192.168.0.105:9091/") - assert.Equal(t, strings.HasSuffix(u, ".gif"), true, "должен заканчиваться на .gif") - } + // из тестовой БД должны получить 3 записи + assert.Equal(t, len(urls), 3, "должны получить ровно 3 записи") +} - // проверим загрузку - url := urls[1] - // fid := baseName() - filename, err := getFilename(url) - assert.Nil(t, err) +// Проверка загрузки из weed +func TestDownload(t *testing.T) { + // для удобства - теперь вместо assert(t...) пишем просто assert(..) + assert := assert.New(t) + url := "http://192.168.0.105:9090/1,15df3bf5a2b6cb" + tmpdir := t.TempDir() - err = download(url, filepath.Join("test", filename)) - assert.Nil(t, err) + // формируем полное имя файла с путем. + filename := filepath.Join(tmpdir, "1,15df3bf5a2b6cb") + err := download(url, filename) + assert.Nil(err) + assert.FileExists(filename) } +// Работает, но не понятно как интерпретировать результаты func BenchmarkDownload(b *testing.B) { seadb, err := NewSeaDB(db) if err != nil { diff --git a/weed.go b/weed.go index dd2c1ee..f158084 100644 --- a/weed.go +++ b/weed.go @@ -29,7 +29,7 @@ func init() { } } -// загружает файл filename на weed и возвращает url загруженного файла +// загружает файл filename на weed сервер и возвращает url загруженного файла func upload(filename string) (string, error) { fid, err := sw.Submit(filename, "", "") if err != nil { @@ -50,6 +50,7 @@ func delete(url string) error { } // загружает файл из weed в filename +// filename должен содержать полный путь func download(url string, filename string) error { fid, err := getFID(url) if err != nil { @@ -66,6 +67,7 @@ func download(url string, filename string) error { if err != nil { return err } + _, err = file.Write(data) if err != nil { return err @@ -86,6 +88,8 @@ func getFID(url string) (string, error) { return items[len(items)-1], nil } +// возвращает имя файла из url без номера volume +// т.е. http://192.168.0.105:9090/1,15df3bf5a2b6cb => 15df3bf5a2b6cb func getFilename(url string) (string, error) { fn, err := getFID(url) if err != nil {