code.gitea.io/gitea@v1.21.7/models/migrations/base/tests.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  //nolint:forbidigo
     5  package base
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"runtime"
    14  	"testing"
    15  
    16  	"code.gitea.io/gitea/models/unittest"
    17  	"code.gitea.io/gitea/modules/base"
    18  	"code.gitea.io/gitea/modules/git"
    19  	"code.gitea.io/gitea/modules/log"
    20  	"code.gitea.io/gitea/modules/setting"
    21  	"code.gitea.io/gitea/modules/testlogger"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	"xorm.io/xorm"
    25  )
    26  
    27  // FIXME: this file shouldn't be in a normal package, it should only be compiled for tests
    28  
    29  // PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0.
    30  // Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from.
    31  //
    32  // fixtures in `models/migrations/fixtures/<TestName>` will be loaded automatically
    33  func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, func()) {
    34  	t.Helper()
    35  	ourSkip := 2
    36  	ourSkip += skip
    37  	deferFn := testlogger.PrintCurrentTest(t, ourSkip)
    38  	assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
    39  	assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
    40  	ownerDirs, err := os.ReadDir(setting.RepoRootPath)
    41  	if err != nil {
    42  		assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
    43  	}
    44  	for _, ownerDir := range ownerDirs {
    45  		if !ownerDir.Type().IsDir() {
    46  			continue
    47  		}
    48  		repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name()))
    49  		if err != nil {
    50  			assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
    51  		}
    52  		for _, repoDir := range repoDirs {
    53  			_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755)
    54  			_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755)
    55  			_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755)
    56  			_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755)
    57  		}
    58  	}
    59  
    60  	if err := deleteDB(); err != nil {
    61  		t.Errorf("unable to reset database: %v", err)
    62  		return nil, deferFn
    63  	}
    64  
    65  	x, err := newXORMEngine()
    66  	assert.NoError(t, err)
    67  	if x != nil {
    68  		oldDefer := deferFn
    69  		deferFn = func() {
    70  			oldDefer()
    71  			if err := x.Close(); err != nil {
    72  				t.Errorf("error during close: %v", err)
    73  			}
    74  			if err := deleteDB(); err != nil {
    75  				t.Errorf("unable to reset database: %v", err)
    76  			}
    77  		}
    78  	}
    79  	if err != nil {
    80  		return x, deferFn
    81  	}
    82  
    83  	if len(syncModels) > 0 {
    84  		if err := x.Sync(syncModels...); err != nil {
    85  			t.Errorf("error during sync: %v", err)
    86  			return x, deferFn
    87  		}
    88  	}
    89  
    90  	fixturesDir := filepath.Join(filepath.Dir(setting.AppPath), "models", "migrations", "fixtures", t.Name())
    91  
    92  	if _, err := os.Stat(fixturesDir); err == nil {
    93  		t.Logf("initializing fixtures from: %s", fixturesDir)
    94  		if err := unittest.InitFixtures(
    95  			unittest.FixturesOptions{
    96  				Dir: fixturesDir,
    97  			}, x); err != nil {
    98  			t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
    99  			return x, deferFn
   100  		}
   101  		if err := unittest.LoadFixtures(x); err != nil {
   102  			t.Errorf("error whilst loading fixtures from %s: %v", fixturesDir, err)
   103  			return x, deferFn
   104  		}
   105  	} else if !os.IsNotExist(err) {
   106  		t.Errorf("unexpected error whilst checking for existence of fixtures: %v", err)
   107  	} else {
   108  		t.Logf("no fixtures found in: %s", fixturesDir)
   109  	}
   110  
   111  	return x, deferFn
   112  }
   113  
   114  func MainTest(m *testing.M) {
   115  	log.RegisterEventWriter("test", testlogger.NewTestLoggerWriter)
   116  
   117  	giteaRoot := base.SetupGiteaRoot()
   118  	if giteaRoot == "" {
   119  		fmt.Println("Environment variable $GITEA_ROOT not set")
   120  		os.Exit(1)
   121  	}
   122  	giteaBinary := "gitea"
   123  	if runtime.GOOS == "windows" {
   124  		giteaBinary += ".exe"
   125  	}
   126  	setting.AppPath = path.Join(giteaRoot, giteaBinary)
   127  	if _, err := os.Stat(setting.AppPath); err != nil {
   128  		fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath)
   129  		os.Exit(1)
   130  	}
   131  
   132  	giteaConf := os.Getenv("GITEA_CONF")
   133  	if giteaConf == "" {
   134  		giteaConf = path.Join(filepath.Dir(setting.AppPath), "tests/sqlite.ini")
   135  		fmt.Printf("Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf)
   136  	}
   137  
   138  	if !path.IsAbs(giteaConf) {
   139  		setting.CustomConf = path.Join(giteaRoot, giteaConf)
   140  	} else {
   141  		setting.CustomConf = giteaConf
   142  	}
   143  
   144  	tmpDataPath, err := os.MkdirTemp("", "data")
   145  	if err != nil {
   146  		fmt.Printf("Unable to create temporary data path %v\n", err)
   147  		os.Exit(1)
   148  	}
   149  
   150  	setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom")
   151  	setting.AppDataPath = tmpDataPath
   152  
   153  	unittest.InitSettings()
   154  	if err = git.InitFull(context.Background()); err != nil {
   155  		fmt.Printf("Unable to InitFull: %v\n", err)
   156  		os.Exit(1)
   157  	}
   158  	setting.LoadDBSetting()
   159  	setting.InitLoggersForTest()
   160  
   161  	exitStatus := m.Run()
   162  
   163  	if err := removeAllWithRetry(setting.RepoRootPath); err != nil {
   164  		fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
   165  	}
   166  	if err := removeAllWithRetry(tmpDataPath); err != nil {
   167  		fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
   168  	}
   169  	os.Exit(exitStatus)
   170  }