Add support for mocking rpmmd
We want to test API methods which calls dnf. Unfortunately, calling dnf is expensive operation - it requires network access and downloading a lot of (meta)data. This commit changes the rpmmd implementation so that it can be mocked.
This commit is contained in:
parent
9970150ed5
commit
495f5b558b
6 changed files with 97 additions and 23 deletions
|
|
@ -38,7 +38,9 @@ func main() {
|
|||
Metalink: "https://mirrors.fedoraproject.org/metalink?repo=fedora-30&arch=x86_64",
|
||||
}
|
||||
|
||||
packages, err := rpmmd.FetchPackageList([]rpmmd.RepoConfig{repo})
|
||||
rpm := rpmmd.NewRPMMD()
|
||||
|
||||
packages, err := rpm.FetchPackageList([]rpmmd.RepoConfig{repo})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
@ -56,7 +58,7 @@ func main() {
|
|||
store := store.New(&stateFile)
|
||||
|
||||
jobAPI := jobqueue.New(logger, store)
|
||||
weldrAPI := weldr.New(repo, packages, logger, store)
|
||||
weldrAPI := weldr.New(rpm, repo, packages, logger, store)
|
||||
|
||||
go jobAPI.Serve(jobListener)
|
||||
weldrAPI.Serve(weldrListener)
|
||||
|
|
|
|||
19
internal/mocks/rpmmd/fixtures.go
Normal file
19
internal/mocks/rpmmd/fixtures.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package rpmmd_mock
|
||||
|
||||
import (
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
)
|
||||
|
||||
var BaseFixture = Fixture{
|
||||
fetchPackageList{
|
||||
rpmmd.PackageList{
|
||||
{Name: "package1"},
|
||||
{Name: "package2"},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
depsolve{
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
33
internal/mocks/rpmmd/rpmmd_mock.go
Normal file
33
internal/mocks/rpmmd/rpmmd_mock.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package rpmmd_mock
|
||||
|
||||
import "github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
|
||||
type fetchPackageList struct {
|
||||
ret rpmmd.PackageList
|
||||
err error
|
||||
}
|
||||
type depsolve struct {
|
||||
ret []rpmmd.PackageSpec
|
||||
err error
|
||||
}
|
||||
|
||||
type Fixture struct {
|
||||
fetchPackageList
|
||||
depsolve
|
||||
}
|
||||
|
||||
type rpmmdMock struct {
|
||||
Fixture Fixture
|
||||
}
|
||||
|
||||
func NewRPMMDMock(fixture Fixture) rpmmd.RPMMD {
|
||||
return &rpmmdMock{Fixture: fixture}
|
||||
}
|
||||
|
||||
func (r *rpmmdMock) FetchPackageList(repos []rpmmd.RepoConfig) (rpmmd.PackageList, error) {
|
||||
return r.Fixture.fetchPackageList.ret, r.Fixture.fetchPackageList.err
|
||||
}
|
||||
|
||||
func (r *rpmmdMock) Depsolve(specs []string, repos []rpmmd.RepoConfig) ([]rpmmd.PackageSpec, error) {
|
||||
return r.Fixture.depsolve.ret, r.Fixture.depsolve.err
|
||||
}
|
||||
|
|
@ -39,6 +39,11 @@ type PackageSpec struct {
|
|||
Arch string `json:"arch,omitempty"`
|
||||
}
|
||||
|
||||
type RPMMD interface {
|
||||
FetchPackageList(repos []RepoConfig) (PackageList, error)
|
||||
Depsolve(specs []string, repos []RepoConfig) ([]PackageSpec, error)
|
||||
}
|
||||
|
||||
func runDNF(command string, arguments interface{}, result interface{}) error {
|
||||
var call = struct {
|
||||
Command string `json:"command"`
|
||||
|
|
@ -80,7 +85,13 @@ func runDNF(command string, arguments interface{}, result interface{}) error {
|
|||
return cmd.Wait()
|
||||
}
|
||||
|
||||
func FetchPackageList(repos []RepoConfig) (PackageList, error) {
|
||||
type rpmmdImpl struct{}
|
||||
|
||||
func NewRPMMD() RPMMD {
|
||||
return &rpmmdImpl{}
|
||||
}
|
||||
|
||||
func (*rpmmdImpl) FetchPackageList(repos []RepoConfig) (PackageList, error) {
|
||||
var arguments = struct {
|
||||
Repos []RepoConfig `json:"repos"`
|
||||
}{repos}
|
||||
|
|
@ -92,7 +103,7 @@ func FetchPackageList(repos []RepoConfig) (PackageList, error) {
|
|||
return packages, err
|
||||
}
|
||||
|
||||
func Depsolve(specs []string, repos []RepoConfig) ([]PackageSpec, error) {
|
||||
func (*rpmmdImpl) Depsolve(specs []string, repos []RepoConfig) ([]PackageSpec, error) {
|
||||
var arguments = struct {
|
||||
PackageSpecs []string `json:"package-specs"`
|
||||
Repos []RepoConfig `json:"repos"`
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
type API struct {
|
||||
store *store.Store
|
||||
|
||||
rpmmd rpmmd.RPMMD
|
||||
repo rpmmd.RepoConfig
|
||||
packages rpmmd.PackageList
|
||||
|
||||
|
|
@ -31,11 +32,12 @@ type API struct {
|
|||
router *httprouter.Router
|
||||
}
|
||||
|
||||
func New(repo rpmmd.RepoConfig, packages rpmmd.PackageList, logger *log.Logger, store *store.Store) *API {
|
||||
func New(rpmmd rpmmd.RPMMD, repo rpmmd.RepoConfig, packages rpmmd.PackageList, logger *log.Logger, store *store.Store) *API {
|
||||
// This needs to be shared with the worker API so that they can communicate with each other
|
||||
// builds := make(chan queue.Build, 200)
|
||||
api := &API{
|
||||
store: store,
|
||||
rpmmd: rpmmd,
|
||||
repo: repo,
|
||||
packages: packages,
|
||||
logger: logger,
|
||||
|
|
@ -467,7 +469,7 @@ func (api *API) modulesInfoHandler(writer http.ResponseWriter, request *http.Req
|
|||
}
|
||||
|
||||
if modulesRequested {
|
||||
project.Dependencies, _ = rpmmd.Depsolve([]string{pkg.Name}, []rpmmd.RepoConfig{api.repo})
|
||||
project.Dependencies, _ = api.rpmmd.Depsolve([]string{pkg.Name}, []rpmmd.RepoConfig{api.repo})
|
||||
}
|
||||
|
||||
projects = append(projects, project)
|
||||
|
|
@ -610,7 +612,7 @@ func (api *API) blueprintsDepsolveHandler(writer http.ResponseWriter, request *h
|
|||
specs[i] += "-*-*.*"
|
||||
}
|
||||
}
|
||||
dependencies, _ := rpmmd.Depsolve(specs, []rpmmd.RepoConfig{api.repo})
|
||||
dependencies, _ := api.rpmmd.Depsolve(specs, []rpmmd.RepoConfig{api.repo})
|
||||
|
||||
blueprints = append(blueprints, entry{blueprint, dependencies})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/mocks/rpmmd"
|
||||
"github.com/osbuild/osbuild-composer/internal/rpmmd"
|
||||
"github.com/osbuild/osbuild-composer/internal/store"
|
||||
"github.com/osbuild/osbuild-composer/internal/weldr"
|
||||
|
|
@ -27,11 +28,6 @@ var repo = rpmmd.RepoConfig{
|
|||
BaseURL: "http://example.com/test/os",
|
||||
}
|
||||
|
||||
var packages = rpmmd.PackageList{
|
||||
{Name: "package1"},
|
||||
{Name: "package2"},
|
||||
}
|
||||
|
||||
func externalRequest(method, path, body string) *http.Response {
|
||||
client := http.Client{
|
||||
Transport: &http.Transport{
|
||||
|
|
@ -161,6 +157,18 @@ func testRoute(t *testing.T, api *weldr.API, external bool, method, path, body s
|
|||
}
|
||||
}
|
||||
|
||||
func createWeldrAPI(fixture rpmmd_mock.Fixture) (*weldr.API, *store.Store) {
|
||||
s := store.New(nil)
|
||||
rpm := rpmmd_mock.NewRPMMDMock(fixture)
|
||||
packageList, err := rpm.FetchPackageList([]rpmmd.RepoConfig{repo})
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return weldr.New(rpm, repo, packageList, nil, s), s
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
var cases = []struct {
|
||||
Path string
|
||||
|
|
@ -197,7 +205,7 @@ func TestBasic(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
testRoute(t, api, true, "GET", c.Path, ``, c.ExpectedStatus, c.ExpectedJSON)
|
||||
}
|
||||
}
|
||||
|
|
@ -214,7 +222,7 @@ func TestBlueprintsNew(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
}
|
||||
}
|
||||
|
|
@ -231,7 +239,7 @@ func TestBlueprintsWorkspace(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
}
|
||||
|
|
@ -252,7 +260,7 @@ func TestBlueprintsInfo(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test1","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test2","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/workspace", `{"name":"test2","description":"Test","packages":[{"name":"systemd","version":"123"}],"version":"0.0.0"}`)
|
||||
|
|
@ -274,7 +282,7 @@ func TestBlueprintsDiff(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/workspace", `{"name":"test","description":"Test","packages":[{"name":"systemd","version":"123"}],"version":"0.0.0"}`)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
|
|
@ -294,7 +302,7 @@ func TestBlueprintsDelete(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
sendHTTP(api, true, "DELETE", "/api/v0/blueprints/delete/test", ``)
|
||||
|
|
@ -331,7 +339,7 @@ func TestCompose(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, c.External, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
testRoute(t, api, c.External, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON, c.IgnoreFields...)
|
||||
sendHTTP(api, c.External, "DELETE", "/api/v0/blueprints/delete/test", ``)
|
||||
|
|
@ -355,8 +363,7 @@ func TestComposeQueue(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
s := store.New(nil)
|
||||
api := weldr.New(repo, packages, nil, s)
|
||||
api, s := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, false, "POST", "/api/v0/blueprints/new", `{"name":"test","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
// create job and leave it waiting
|
||||
sendHTTP(api, false, "POST", "/api/v0/compose", `{"blueprint_name": "test","compose_type": "tar","branch": "master"}`)
|
||||
|
|
@ -390,7 +397,7 @@ func TestSourcesNew(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
sendHTTP(api, true, "DELETE", "/api/v0/projects/source/delete/fish", ``)
|
||||
}
|
||||
|
|
@ -409,7 +416,7 @@ func TestSourcesDelete(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
api := weldr.New(repo, packages, nil, store.New(nil))
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
sendHTTP(api, true, "POST", "/api/v0/projects/source/new", `{"name": "fish","url": "https://download.opensuse.org/repositories/shells:/fish:/release:/3/Fedora_29/","type": "yum-baseurl","check_ssl": false,"check_gpg": false}`)
|
||||
testRoute(t, api, true, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
|
||||
sendHTTP(api, true, "DELETE", "/api/v0/projects/source/delete/fish", ``)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue