Skip to content

Commit

Permalink
extbldr: added mock subcommand and testUtil
Browse files Browse the repository at this point in the history
added mock subcommand to build RPM from SRPMs. This internally calls the
mock tool to build the RPM in the architecture specified.
works with default config as of now. quiet option added for mock.
Added a testUtil file to collate common test functions under util
package.
  • Loading branch information
shyammohan-arista committed Sep 7, 2022
1 parent f531a48 commit ba3572a
Show file tree
Hide file tree
Showing 9 changed files with 322 additions and 26 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/extbldr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on: # yamllint disable-line rule:truthy
branches:
- 'main'

env:
TEST_TAG: extbldr:test

jobs:
gobuild:
name: Go lint and build
Expand Down Expand Up @@ -66,6 +69,24 @@ jobs:
secrets: |
GIT_AUTH_TOKEN=${{ secrets.GITHUB_TOKEN }}
load: true
tags: ${{ env.TEST_TAG }}
target: builder
- name: Test privileged
run: |
docker run --rm --privileged \
${{ env.TEST_TAG }} sh -c 'go test ./... -tags=privileged'
- name: Dockerfile build without publish
uses: docker/build-push-action@v3
with:
# Dockerfile is within subdirectory
context: "{{defaultContext}}:extbldr"

# GIT_AUTH_TOKEN is unset for non-default context
secrets: |
GIT_AUTH_TOKEN=${{ secrets.GITHUB_TOKEN }}
# Publish is done by Arista docker-library to push to on-prem registry
# This just checks the docker build and can work off-prem.
target: deploy
push: false
2 changes: 1 addition & 1 deletion extbldr/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ RUN go build -o /home/extbldr-robot/bin/extbldr && \
go vet ./...

FROM base as deploy
COPY --from=builder /home/extbldr-robot/bin/extbldr /usr/bin/
COPY --from=builder /home/extbldr-robot/bin/extbldr /usr/bin/
29 changes: 29 additions & 0 deletions extbldr/cmd/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2022 Arista Networks, Inc. All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

package cmd

import (
"github.com/spf13/cobra"

"extbldr/impl"
)

var arch string

var mockcmd = &cobra.Command{
Use: "mock -t <Arch> -p <Package>",
Short: "Use mock to build the RPMS from the SRPMS built previously.",
Long: `Use mock to build The RPMS for the specified architecture from the specified SRPM package in <SrcDir>/<package>/rpmbuild/SRPMS and output placed inside <WorkingDir>/<package>/RPMS.`,
RunE: func(cmd *cobra.Command, args []string) error {
pkg, _ := cmd.Flags().GetString("package")
subpkg, _ := cmd.Flags().GetString("subpackage")
err := impl.Mock(arch, pkg, subpkg)
return err
},
}

func init() {
mockcmd.Flags().StringVarP(&arch, "target", "t", "", "target architecture for the RPM")
rootCmd.AddCommand(mockcmd)
}
88 changes: 88 additions & 0 deletions extbldr/cmd/mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) 2022 Arista Networks, Inc. All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

//go:build privileged
// +build privileged

package cmd

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"

"extbldr/util"
)

func testMock(t *testing.T, workingDir string, pkgName string, quiet bool) {
viper.Set("WorkingDir", workingDir)
viper.Set("SrcDir", "testData")
util.SetupManifest(t, workingDir, pkgName, filepath.Join(pkgName, "manifest.yml"))
defer viper.Reset()
args := []string{"mock", "--target", "x86_64", "--package", pkgName}
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
if quiet {
args = append(args, "--quiet")
os.Stdout = w
}
rootCmd.SetArgs(args)

cmdErr := rootCmd.Execute()
assert.NoError(t, cmdErr)

if quiet {
w.Close()
out, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err)
}
assert.Empty(t, out)
os.Stdout = rescueStdout
}
}

func TestMock(t *testing.T) {
t.Log("Create temporary working directory")

workingDir, err := os.MkdirTemp("", "mock-test")
if err != nil {
t.Fatal(err)
}
baseName := "debugedit-1"
basePkgName := "debugedit"
srpmPath := filepath.Join(workingDir, basePkgName, "rpmbuild", "SRPMS")
err = os.MkdirAll(srpmPath, os.ModePerm)
if err != nil {
t.Fatal(err)
}

sampleSRPMPath := filepath.Join("testData", "mock-1", "debugedit-5.0-3.el9.src.rpm")
_, statErr := os.Stat(sampleSRPMPath)
if statErr != nil {
t.Fatal(statErr)
}

targetPath, absErr := filepath.Abs(sampleSRPMPath)
if absErr != nil {
t.Fatal(absErr)
}
linkPath := filepath.Join(srpmPath, "debugedit-5.0-3.el9.src.rpm")
symlinkErr := os.Symlink(targetPath, linkPath)
if symlinkErr != nil {
t.Fatal(symlinkErr)
}

defer os.RemoveAll(workingDir)

t.Logf("WorkingDir: %s", workingDir)
t.Log("Test mock from SRPM")
testMock(t, workingDir, baseName, false)

t.Log("Test mock from SRPM quiet")
testMock(t, workingDir, baseName, true)
}
Binary file not shown.
107 changes: 107 additions & 0 deletions extbldr/impl/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) 2022 Arista Networks, Inc. All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

package impl

import (
"fmt"
"path/filepath"

"github.com/spf13/viper"

"extbldr/manifest"
"extbldr/util"
)

func mockSubPkg(arch string, pkg string) error {
var mockErr error
//setup working dir
baseDir := viper.GetString("WorkingDir")

//create rpmpath if nor there
rpmPath := filepath.Join(baseDir, pkg, "RPMS")
logPath := filepath.Join(baseDir, pkg, "logs")
srpmPath := filepath.Join(baseDir, pkg, "rpmbuild", "SRPMS")
scratchPath := filepath.Join(baseDir, pkg, "scratch")
creatErr := util.MaybeCreateDir("impl.mockSubPkg", rpmPath)
if creatErr != nil {
return fmt.Errorf("impl.mockSubPkg: Creating %s errored out with %s", rpmPath, creatErr)
}

//setup args
targetArg := "--target=" + arch

srpmName, srpmErr := util.GetMatchingFileNamesFromDir(srpmPath, "(?i).*\\.src\\.rpm")
if srpmErr != nil {
return fmt.Errorf("impl.mockSubPkg: reading SRPMS errored out with %s", srpmErr)
}
srpmFullPath := filepath.Join(srpmPath, srpmName[0]) ////expecting single file

//cleanup RPM, logs, scratch
cleanupErr := util.RunSystemCmd("rm", "-rf", rpmPath)
if cleanupErr != nil {
return fmt.Errorf("impl.mockSubPkg: cleanup %s errored out with %s", rpmPath, cleanupErr)
}

cleanupErr = util.RunSystemCmd("rm", "-rf", logPath)
if cleanupErr != nil {
return fmt.Errorf("impl.mockSubPkg: cleanup %s errored out with %s", logPath, cleanupErr)
}

cleanupErr = util.RunSystemCmd("rm", "-rf", scratchPath)
if cleanupErr != nil {
return fmt.Errorf("impl.mockSubPkg: cleanup %s errored out with %s", scratchPath, cleanupErr)
}

//run cmd
if util.GlobalVar.Quiet {
mockErr = util.RunSystemCmd("mock", "--quiet", fmt.Sprintf("--resultdir=%s", rpmPath), targetArg, srpmFullPath)
} else {
mockErr = util.RunSystemCmd("mock", fmt.Sprintf("--resultdir=%s", rpmPath), targetArg, srpmFullPath)
}
if mockErr != nil {
return fmt.Errorf("impl.mockSubPkg: mock on %s to arch %s errored out with %s",
pkg, arch, mockErr)
}

// move out logs, srpm from resultdir
srpmName, srpmErr = util.GetMatchingFileNamesFromDir(rpmPath, "(?i).*\\.src\\.rpm")
if srpmErr != nil {
return fmt.Errorf("impl.mockSubPkg: reading SRPMS errored out with %s", srpmErr)
}
srpmErr = util.CopyFilesToDir(srpmName, rpmPath, scratchPath)
if srpmErr != nil {
return fmt.Errorf("impl.mockSubPkg: moving SRPMS errored out with %s", srpmErr)
}
logName, logErr := util.GetMatchingFileNamesFromDir(rpmPath, "(?i).*\\.log")
if logErr != nil {
return fmt.Errorf("impl.mockSubPkg: reading log files errored out with %s", logErr)
}
logErr = util.CopyFilesToDir(logName, rpmPath, logPath)
if srpmErr != nil {
return fmt.Errorf("impl.mockSubPkg: moving logs errored out with %s", srpmErr)
}
return nil
}

// Mock builds the RPM in specified architecture and
// copies it to {WorkingDir}/<pkg>/RPMS
func Mock(arch string, pkg string, subPkg string) error {
pkgManifest, loadManifestErr := manifest.LoadManifest(pkg)
if loadManifestErr != nil {
return loadManifestErr
}
var subPkgSpecified bool = (subPkg != "")
for _, subPkgSpec := range pkgManifest.SubPackage {
thisSubPkgName := subPkgSpec.Name
if subPkgSpecified && (subPkg != thisSubPkgName) {
continue
}
subPkgErr := mockSubPkg(arch, subPkgSpec.Name)
if subPkgErr != nil {
return fmt.Errorf("impl.Mock: subPkg %s mock errored out %s", subPkgSpec.Name, subPkgErr)
}
}

return nil
}
28 changes: 3 additions & 25 deletions extbldr/manifest/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ package manifest
import (
"github.com/stretchr/testify/assert"
"os"
"path/filepath"
"testing"

"github.com/spf13/viper"

"extbldr/util"
)

func testLoad(t *testing.T, pkg string) {
Expand All @@ -18,29 +19,6 @@ func testLoad(t *testing.T, pkg string) {
assert.NotNil(t, manifest)
}

func setupManifest(t *testing.T, baseDir string, pkg string, sampleFile string) {
pkgDir := filepath.Join(baseDir, pkg)
os.RemoveAll(pkgDir)
os.Mkdir(pkgDir, 0775)

sampleManifestPath := filepath.Join("testData", sampleFile)
_, statErr := os.Stat(sampleManifestPath)
if statErr != nil {
t.Fatal(statErr)
}

targetPath, absErr := filepath.Abs(sampleManifestPath)
if absErr != nil {
t.Fatal(absErr)
}
linkPath := filepath.Join(pkgDir, "manifest.yml")
symlinkErr := os.Symlink(targetPath, linkPath)
if symlinkErr != nil {
t.Fatal(symlinkErr)
}

}

func TestManifest(t *testing.T) {
t.Log("Create temporary working directory")
dir, err := os.MkdirTemp("", "manifest-test")
Expand All @@ -53,7 +31,7 @@ func TestManifest(t *testing.T) {
defer viper.Reset()

t.Log("Copy sample manifest to test directory")
setupManifest(t, dir, "pkg1", "sampleManifest1.yml")
util.SetupManifest(t, dir, "pkg1", "sampleManifest1.yml")

t.Log("Testing Load")
testLoad(t, "pkg1")
Expand Down
34 changes: 34 additions & 0 deletions extbldr/util/testUtil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2022 Arista Networks, Inc. All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

package util

import (
"os"
"path/filepath"
"testing"
)

// SetupManifest used to setup a test manifest from testdata for manifest functionality testing
func SetupManifest(t *testing.T, baseDir string, pkg string, sampleFile string) {
pkgDir := filepath.Join(baseDir, pkg)
os.RemoveAll(pkgDir)
os.Mkdir(pkgDir, 0775)

sampleManifestPath := filepath.Join("testData", sampleFile)
_, statErr := os.Stat(sampleManifestPath)
if statErr != nil {
t.Fatal(statErr)
}

targetPath, absErr := filepath.Abs(sampleManifestPath)
if absErr != nil {
t.Fatal(absErr)
}
linkPath := filepath.Join(pkgDir, "manifest.yml")
symlinkErr := os.Symlink(targetPath, linkPath)
if symlinkErr != nil {
t.Fatal(symlinkErr)
}

}
Loading

0 comments on commit ba3572a

Please sign in to comment.