Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing: Add integration testsuite #60

Merged
merged 17 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/coverage-upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Coverage Upload

on:
workflow_run:
workflows: [testing]
types:
- completed

jobs:
run_tests:
runs-on: ubuntu-latest
steps:
# https://github.com/actions/github-script
# Based on: https://github.com/orgs/community/discussions/34652
- name: 'Download artifact'
uses: actions/github-script@v7
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "coverage-report"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/coverage-report.zip`, Buffer.from(download.data));
- name: 'Unzip artifact'
run: unzip coverage-report.zip
# https://github.com/actions/download-artifact
# - name: Download artifact
# id: download-artifact
# uses: actions/download-artifact@v4
# with:
# run-id: ${{ github.event.workflow_run.id }}
# https://github.com/codacy/codacy-coverage-reporter-action
# - name: Run codacy-coverage-reporter
# uses: codacy/codacy-coverage-reporter-action@v1
# with:
# project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
# coverage-reports: coverage.xml
- name: Publish Code Coverage Results
run: |
auth="--project-token ${{ secrets.CODACY_PROJECT_TOKEN }}"
commit_uuid="--commit-uuid ${{ github.event.workflow_run.head_sha }}"

bash <(curl -Ls https://coverage.codacy.com/get.sh) report $auth $commit_uuid --force-coverage-parser go -r coverage.out --partial &&\
bash <(curl -Ls https://coverage.codacy.com/get.sh) final $auth $commit_uuid
70 changes: 70 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: testing

on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:

permissions:
contents: read

jobs:
test:
name: Integration Tests (Cobbler ${{ matrix.cobbler_version }})
runs-on: ubuntu-latest
strategy:
matrix:
cobbler_version:
# - d8f60bbf14a838c8c8a1dba98086b223e35fe70a # 3.3.0 - TypeError during import
- f5b0599acce32de4288c76e4f601aece0c664fed # 3.3.1
# - 9044aa990a94752fa5bd5a24051adde099280bfa # 3.3.2 - Testing Docker Image broken
# - 5c498dbf2af6e3782b37605a477759e1aacc16b2 # 3.3.3 - Testing Docker Image broken
- 3ed865b79ce69fca7464e0957f4bcadcc9917a9d # 3.3.4
- 718e3256a5989941e8a678404fdea07364255637 # 3.3.5
- df356046f3cf27be62a61001b982d5983800cfd9 # 3.3.6
fail-fast: false
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
id: go
- name: Install system dependencies
run: |
sudo apt-get install -y xorriso
- name: Get dependencies
run: |
go mod download
- name: Replace git version hash
run: |
sed -i "s/cobbler_commit=.*/cobbler_commit=${{ matrix.cobbler_version }}/" testing/start.sh
- name: Restore OS ISO
id: cache-iso-restore
uses: actions/cache/restore@v4
with:
path: |
*.iso
key: ${{ runner.os }}-${{ matrix.cobbler_version }}-iso
- name: Make Test
run: |
make test
- name: Save OS ISO
id: cache-iso-save
uses: actions/cache/save@v4
with:
path: |
*.iso
key: ${{ steps.cache-iso-restore.outputs.cache-primary-key }}
# https://github.com/actions/upload-artifact
- name: Upload coverage report to GH artifacts
if: matrix.cobbler_version == 'df356046f3cf27be62a61001b982d5983800cfd9'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.out
if-no-files-found: error
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ docs/_build

# goreleaser
dist/

# Tests
testing/cobbler_source/
extracted_iso_image/
*.iso
coverage.out
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
BINARY_NAME=cobbler
EXECUTOR?=docker
COBBLER_SERVER_URL=http://localhost:8081/cobbler_api
TEST?=$$(go list ./... |grep -v 'vendor')

build:
@echo "building package"
Expand Down Expand Up @@ -28,6 +30,10 @@ run:
go build -o ${BINARY_NAME} main.go
./${BINARY_NAME}

test:
@./testing/start.sh ${COBBLER_SERVER_URL}
go test -v -coverprofile="coverage.out" -covermode="atomic" $(TEST)

shell_completions:
@mkdir -p config/completions/bash
@mkdir -p config/completions/fish
Expand Down
87 changes: 44 additions & 43 deletions cmd/aclsetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,52 @@ import (
"github.com/spf13/cobra"
)

// aclsetupCmd represents the aclsetup command
var aclsetupCmd = &cobra.Command{
Use: "aclsetup",
Short: "Adjust the access control list",
Long: "Configures users/groups to run the Cobbler CLI as non-root.",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
generateCobblerClient()
addUserOption, err := cmd.Flags().GetString("adduser")
if err != nil {
return err
}
addGroupOption, err := cmd.Flags().GetString("addgroup")
if err != nil {
return err
}
removeUserOption, err := cmd.Flags().GetString("removeuser")
if err != nil {
return err
}
removeGroupOption, err := cmd.Flags().GetString("removegroup")
if err != nil {
return err
}
aclSetupOptions := cobblerclient.AclSetupOptions{
AddUser: addUserOption,
AddGroup: addGroupOption,
RemoveUser: removeUserOption,
RemoveGroup: removeGroupOption,
}
eventId, err := Client.BackgroundAclSetup(aclSetupOptions)
if err != nil {
return err
}
fmt.Println("Event ID: ", eventId)
return nil
},
}

func init() {
rootCmd.AddCommand(aclsetupCmd)

//local flags
// NewAclSetupCmd builds a new command that represent the aclsetup action.
func NewAclSetupCmd() *cobra.Command {
aclsetupCmd := &cobra.Command{
Use: "aclsetup",
Short: "Adjust the access control list",
Long: "Configures users/groups to run the Cobbler CLI as non-root.",
RunE: func(cmd *cobra.Command, args []string) error {
err := generateCobblerClient()
if err != nil {
return err
}
addUserOption, err := cmd.Flags().GetString("adduser")
if err != nil {
return err
}
addGroupOption, err := cmd.Flags().GetString("addgroup")
if err != nil {
return err
}
removeUserOption, err := cmd.Flags().GetString("removeuser")
if err != nil {
return err
}
removeGroupOption, err := cmd.Flags().GetString("removegroup")
if err != nil {
return err
}
aclSetupOptions := cobblerclient.AclSetupOptions{
AddUser: addUserOption,
AddGroup: addGroupOption,
RemoveUser: removeUserOption,
RemoveGroup: removeGroupOption,
}
eventId, err := Client.BackgroundAclSetup(aclSetupOptions)
if err != nil {
return err
}
fmt.Fprintln(cmd.OutOrStdout(), "Event ID: ", eventId)
return nil
},
}
aclsetupCmd.Flags().String("adduser", "", "give acls to this user")
aclsetupCmd.Flags().String("addgroup", "", "give acls to this group")
aclsetupCmd.Flags().String("removeuser", "", "remove acls from this user")
aclsetupCmd.Flags().String("removegroup", "", "remove acls from this user")
aclsetupCmd.MarkFlagsMutuallyExclusive("adduser", "addgroup", "removeuser", "removegroup")
aclsetupCmd.MarkFlagsOneRequired("adduser", "addgroup", "removeuser", "removegroup")
return aclsetupCmd
}
76 changes: 76 additions & 0 deletions cmd/aclsetup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cmd

import (
"bytes"
"fmt"
"github.com/cobbler/cobblerclient"
"github.com/spf13/cobra"
"io"
"strings"
"testing"
)

func Test_AclSetupCmd(t *testing.T) {
type args struct {
command []string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "adduser",
args: args{command: []string{"--config", "../testing/.cobbler.yaml", "aclsetup", "--adduser", "cobbler"}},
want: "Event ID:",
wantErr: false,
},
{
name: "addgroup",
args: args{command: []string{"--config", "../testing/.cobbler.yaml", "aclsetup", "--addgroup", "cobbler"}},
want: "Event ID:",
wantErr: false,
},
{
name: "removeuser",
args: args{command: []string{"--config", "../testing/.cobbler.yaml", "aclsetup", "--removeuser", "cobbler"}},
want: "Event ID:",
wantErr: false,
},
{
name: "removegroup",
args: args{command: []string{"--config", "../testing/.cobbler.yaml", "aclsetup", "--removegroup", "cobbler"}},
want: "Event ID:",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Arrange
cobra.OnInitialize(initConfig, setupLogger)
rootCmd := NewRootCmd()
rootCmd.SetArgs(tt.args.command)
stdout := bytes.NewBufferString("")
stderr := bytes.NewBufferString("")
rootCmd.SetOut(stdout)
rootCmd.SetErr(stderr)

// Act
err := rootCmd.Execute()

// Assert
cobblerclient.FailOnError(t, err)
FailOnNonEmptyStream(t, stderr)
stdoutBytes, err := io.ReadAll(stdout)
if err != nil {
t.Fatal(err)
}
stdoutString := string(stdoutBytes)
if !strings.Contains(stdoutString, tt.want) {
fmt.Println(stdoutString)
t.Fatal("No Event ID present")
}
})
}
}
Loading
Loading