From 4b68df5aaa1aaf4b6561dec8b5bf6135e8daa5fa Mon Sep 17 00:00:00 2001 From: Enno Gotthold Date: Thu, 31 Oct 2024 11:46:04 +0100 Subject: [PATCH] Testing: Add integration testsuite --- .github/workflows/coverage-upload.yml | 55 +++ .github/workflows/testing.yml | 70 ++++ .gitignore | 6 + Makefile | 6 + cmd/aclsetup_test.go | 76 +++++ cmd/buildiso_test.go | 117 +++++++ cmd/distro_test.go | 456 +++++++++++++++++++++++++ cmd/event_test.go | 87 +++++ cmd/file_test.go | 459 ++++++++++++++++++++++++++ cmd/hardlink_test.go | 38 +++ cmd/image_test.go | 454 +++++++++++++++++++++++++ cmd/import_test.go | 58 ++++ cmd/list_test.go | 38 +++ cmd/menu_test.go | 454 +++++++++++++++++++++++++ cmd/mgmtclass_test.go | 454 +++++++++++++++++++++++++ cmd/mkloaders_test.go | 38 +++ cmd/package_test.go | 454 +++++++++++++++++++++++++ cmd/profile_test.go | 455 +++++++++++++++++++++++++ cmd/replicate_test.go | 58 ++++ cmd/repo_test.go | 454 +++++++++++++++++++++++++ cmd/report_test.go | 38 +++ cmd/reposync_test.go | 70 ++++ cmd/setting_test.go | 60 ++++ cmd/signature_test.go | 92 ++++++ cmd/sync_test.go | 86 +++++ cmd/system_test.go | 455 +++++++++++++++++++++++++ cmd/testing.go | 20 ++ cmd/utils_test.go | 2 - cmd/validateAutoinstalls_test.go | 38 +++ cmd/version_test.go | 38 +++ testing/.cobbler.yaml | 3 + testing/compose.yml | 17 + testing/start.sh | 70 ++++ 33 files changed, 5274 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/coverage-upload.yml create mode 100644 .github/workflows/testing.yml create mode 100644 cmd/aclsetup_test.go create mode 100644 cmd/buildiso_test.go create mode 100644 cmd/distro_test.go create mode 100644 cmd/event_test.go create mode 100644 cmd/file_test.go create mode 100644 cmd/hardlink_test.go create mode 100644 cmd/image_test.go create mode 100644 cmd/import_test.go create mode 100644 cmd/list_test.go create mode 100644 cmd/menu_test.go create mode 100644 cmd/mgmtclass_test.go create mode 100644 cmd/mkloaders_test.go create mode 100644 cmd/package_test.go create mode 100644 cmd/profile_test.go create mode 100644 cmd/replicate_test.go create mode 100644 cmd/repo_test.go create mode 100644 cmd/report_test.go create mode 100644 cmd/reposync_test.go create mode 100644 cmd/setting_test.go create mode 100644 cmd/signature_test.go create mode 100644 cmd/sync_test.go create mode 100644 cmd/system_test.go create mode 100644 cmd/testing.go create mode 100644 cmd/validateAutoinstalls_test.go create mode 100644 cmd/version_test.go create mode 100644 testing/.cobbler.yaml create mode 100644 testing/compose.yml create mode 100755 testing/start.sh diff --git a/.github/workflows/coverage-upload.yml b/.github/workflows/coverage-upload.yml new file mode 100644 index 0000000..0ea36f0 --- /dev/null +++ b/.github/workflows/coverage-upload.yml @@ -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 \ No newline at end of file diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 0000000..a3fce4c --- /dev/null +++ b/.github/workflows/testing.yml @@ -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 diff --git a/.gitignore b/.gitignore index 654c4c8..96c5ae2 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,9 @@ docs/_build # goreleaser dist/ + +# Tests +testing/cobbler_source/ +extracted_iso_image/ +*.iso +coverage.out diff --git a/Makefile b/Makefile index 75d4845..916f247 100644 --- a/Makefile +++ b/Makefile @@ -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" @@ -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 diff --git a/cmd/aclsetup_test.go b/cmd/aclsetup_test.go new file mode 100644 index 0000000..89d06ef --- /dev/null +++ b/cmd/aclsetup_test.go @@ -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") + } + }) + } +} diff --git a/cmd/buildiso_test.go b/cmd/buildiso_test.go new file mode 100644 index 0000000..d8d7f3c --- /dev/null +++ b/cmd/buildiso_test.go @@ -0,0 +1,117 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_BuildisoStandaloneCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "buildiso", "--standalone"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "airgapped", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "buildiso", "--airgapped"}}, + 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") + } + }) + } +} + +func Test_BuildisoNetinstallCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "systems", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "buildiso", "--systems", "test"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "nodns", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "buildiso", "--systems", "test", "--exclude-dns"}}, + 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") + } + }) + } +} diff --git a/cmd/distro_test.go b/cmd/distro_test.go new file mode 100644 index 0000000..6ec50ea --- /dev/null +++ b/cmd/distro_test.go @@ -0,0 +1,456 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createDistro(client cobbler.Client, name string) (*cobbler.Distro, error) { + distro := cobbler.NewDistro() + distro.Name = name + distro.Kernel = "/extracted_iso_image/install/vmlinuz" + distro.Initrd = "/extracted_iso_image/install/initrd.gz" + return client.CreateDistro(distro) +} + +func removeDistro(client cobbler.Client, name string) error { + return client.DeleteDistro(name) +} + +func Test_DistroAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "add", "--name", "test-plain", "--kernel", "/extracted_iso_image/install/vmlinuz", "--initrd", "/extracted_iso_image/install/initrd.gz"}}, + want: "Distro test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_DistroCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "copy", "--name", "distro-to-copy", "--newname", "copied-distro"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeDistro(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetDistro(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_DistroEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "edit", "--name", "test-distro-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedDistro, err := Client.GetDistro(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedDistro.Comment != "testcomment" { + t.Fatal("distro update wasn't successful") + } + }) + } +} + +func Test_DistroFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "find", "--name", "test-distro-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + distroName := "test-distro-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, distroName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createDistro(Client, distroName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, distroName) { + fmt.Println(stdoutString) + t.Fatal("distro not successfully found") + } + }) + } +} + +func Test_DistroListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "list"}}, + want: "distros:", + 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 + cobbler.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("distro list marker not located in output") + } + }) + } +} + +func Test_DistroRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "remove", "--name", "test-distro-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createDistro(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("distro", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("distro not successfully removed") + } + }) + } +} + +func Test_DistroRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "rename", "--name", "test-distro-rename", "--newname", "test-distro-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + distroName := "test-distro-rename" + newDistroName := "test-distro-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, newDistroName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createDistro(Client, distroName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("distro", distroName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("distro not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("distro", newDistroName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("distro not successfully renamed (new name not present)") + } + }) + } +} + +func Test_DistroReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "distro", "report", "--name", "test-distro-report"}}, + want: ": test-distro-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + distroName := "test-distro-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeDistro(Client, distroName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createDistro(Client, distroName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/event_test.go b/cmd/event_test.go new file mode 100644 index 0000000..12bb1ab --- /dev/null +++ b/cmd/event_test.go @@ -0,0 +1,87 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_EventStatusCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "event", "status", "--event-id", "garbage"}) + stdout := bytes.NewBufferString("") + stderr := bytes.NewBufferString("") + rootCmd.SetOut(stdout) + rootCmd.SetErr(stderr) + + // Act + err := rootCmd.Execute() + + // Assert + if err == nil { + t.Fatal("expected error, got none") + } + if !strings.Contains(err.Error(), "no event with that id") { + t.Fatal("server didn't complain about garbage event id") + } +} + +func Test_EventListCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "event", "list"}) + 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, "Time (last transitioned)") { + fmt.Println(stdoutString) + t.Fatal("no table header with time present") + } +} + +func Test_EventLogCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "event", "log", "--event-id", "garbage"}) + 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, "?") { + fmt.Println(stdoutString) + t.Fatal("server didn't complain about garbage event id") + } +} diff --git a/cmd/file_test.go b/cmd/file_test.go new file mode 100644 index 0000000..c35b3c3 --- /dev/null +++ b/cmd/file_test.go @@ -0,0 +1,459 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createFile(client cobbler.Client, name string) (*cobbler.File, error) { + file := cobbler.NewFile() + file.Name = name + file.Path = "/my/custom/folder" + file.Owner = "root" + file.Group = "root" + file.Mode = "0755" + file.IsDir = true + return client.CreateFile(file) +} + +func removeFile(client cobbler.Client, name string) error { + return client.DeleteFile(name) +} + +func Test_FileAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "add", "--name", "test-plain", "--path", "/my/custom/folder", "--group", "root", "--owner", "root", "--mode", "0755", "--is-dir", "true"}}, + want: "File test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_FileCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "copy", "--name", "file-to-copy", "--newname", "copied-file"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeFile(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetFile(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_FileEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "edit", "--name", "test-file-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedFile, err := Client.GetFile(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedFile.Comment != "testcomment" { + t.Fatal("file update wasn't successful") + } + }) + } +} + +func Test_FileFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "find", "--name", "test-file-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + fileName := "test-file-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, fileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createFile(Client, fileName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, fileName) { + fmt.Println(stdoutString) + t.Fatal("file not successfully found") + } + }) + } +} + +func Test_FileListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "list"}}, + want: "files:", + 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 + cobbler.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("file list marker not located in output") + } + }) + } +} + +func Test_FileRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "remove", "--name", "test-file-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createFile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("file", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("file not successfully removed") + } + }) + } +} + +func Test_FileRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "rename", "--name", "test-file-rename", "--newname", "test-file-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + fileName := "test-file-rename" + newFileName := "test-file-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, newFileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createFile(Client, fileName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("file", fileName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("file not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("file", newFileName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("file not successfully renamed (new name not present)") + } + }) + } +} + +func Test_FileReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "file", "report", "--name", "test-file-report"}}, + want: ": test-file-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + fileName := "test-file-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeFile(Client, fileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createFile(Client, fileName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/hardlink_test.go b/cmd/hardlink_test.go new file mode 100644 index 0000000..5c491ca --- /dev/null +++ b/cmd/hardlink_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_HardlinkCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "hardlink"}) + 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, "Event ID:") { + fmt.Println(stdoutString) + t.Fatal("No Event ID present") + } +} diff --git a/cmd/image_test.go b/cmd/image_test.go new file mode 100644 index 0000000..b2b0560 --- /dev/null +++ b/cmd/image_test.go @@ -0,0 +1,454 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createImage(client cobbler.Client, name string) (*cobbler.Image, error) { + image := cobbler.NewImage() + image.Name = name + return client.CreateImage(image) +} + +func removeImage(client cobbler.Client, name string) error { + return client.DeleteImage(name) +} + +func Test_ImageAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "add", "--name", "test-plain"}}, + want: "Image test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_ImageCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "copy", "--name", "image-to-copy", "--newname", "copied-image"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeImage(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetImage(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_ImageEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "edit", "--name", "test-image-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedImage, err := Client.GetImage(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedImage.Comment != "testcomment" { + t.Fatal("image update wasn't successful") + } + }) + } +} + +func Test_ImageFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "find", "--name", "test-image-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + imageName := "test-image-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, imageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createImage(Client, imageName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, imageName) { + fmt.Println(stdoutString) + t.Fatal("image not successfully found") + } + }) + } +} + +func Test_ImageListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "list"}}, + want: "images:", + 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 + cobbler.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("image list marker not located in output") + } + }) + } +} + +func Test_ImageRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "remove", "--name", "test-image-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createImage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("image", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("image not successfully removed") + } + }) + } +} + +func Test_ImageRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "rename", "--name", "test-image-rename", "--newname", "test-image-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + imageName := "test-image-rename" + newImageName := "test-image-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, newImageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createImage(Client, imageName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("image", imageName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("image not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("image", newImageName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("image not successfully renamed (new name not present)") + } + }) + } +} + +func Test_ImageReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "image", "report", "--name", "test-image-report"}}, + want: ": test-image-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + imageName := "test-image-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeImage(Client, imageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createImage(Client, imageName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/import_test.go b/cmd/import_test.go new file mode 100644 index 0000000..dc87b27 --- /dev/null +++ b/cmd/import_test.go @@ -0,0 +1,58 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ImportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "import"}}, + 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") + } + }) + } +} diff --git a/cmd/list_test.go b/cmd/list_test.go new file mode 100644 index 0000000..1483d1b --- /dev/null +++ b/cmd/list_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ListCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "list"}) + 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, "distros:") && strings.Contains(stdoutString, "profiles")) { + fmt.Println(stdoutString) + t.Fatal("no heading for distros and profiles present") + } +} diff --git a/cmd/menu_test.go b/cmd/menu_test.go new file mode 100644 index 0000000..4f6ad2f --- /dev/null +++ b/cmd/menu_test.go @@ -0,0 +1,454 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createMenu(client cobbler.Client, name string) (*cobbler.Menu, error) { + menu := cobbler.NewMenu() + menu.Name = name + return client.CreateMenu(menu) +} + +func removeMenu(client cobbler.Client, name string) error { + return client.DeleteMenu(name) +} + +func Test_MenuAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "add", "--name", "test-plain"}}, + want: "Menu test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_MenuCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "copy", "--name", "menu-to-copy", "--newname", "copied-menu"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeMenu(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetMenu(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_MenuEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "edit", "--name", "test-menu-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedMenu, err := Client.GetMenu(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedMenu.Comment != "testcomment" { + t.Fatal("menu update wasn't successful") + } + }) + } +} + +func Test_MenuFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "find", "--name", "test-menu-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + menuName := "test-menu-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, menuName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMenu(Client, menuName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, menuName) { + fmt.Println(stdoutString) + t.Fatal("menu not successfully found") + } + }) + } +} + +func Test_MenuListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "list"}}, + want: "menus:", + 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 + cobbler.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("menu list marker not located in output") + } + }) + } +} + +func Test_MenuRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "remove", "--name", "test-menu-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createMenu(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("menu", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("menu not successfully removed") + } + }) + } +} + +func Test_MenuRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "rename", "--name", "test-menu-rename", "--newname", "test-menu-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + menuName := "test-menu-rename" + newMenuName := "test-menu-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, newMenuName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMenu(Client, menuName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("menu", menuName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("menu not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("menu", newMenuName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("menu not successfully renamed (new name not present)") + } + }) + } +} + +func Test_MenuReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "menu", "report", "--name", "test-menu-report"}}, + want: ": test-menu-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + menuName := "test-menu-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMenu(Client, menuName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMenu(Client, menuName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/mgmtclass_test.go b/cmd/mgmtclass_test.go new file mode 100644 index 0000000..e0f71dd --- /dev/null +++ b/cmd/mgmtclass_test.go @@ -0,0 +1,454 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createMgmtClass(client cobbler.Client, name string) (*cobbler.MgmtClass, error) { + mgmtclass := cobbler.NewMgmtClass() + mgmtclass.Name = name + return client.CreateMgmtClass(mgmtclass) +} + +func removeMgmtClass(client cobbler.Client, name string) error { + return client.DeleteMgmtClass(name) +} + +func Test_MgmtClassAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "add", "--name", "test-plain"}}, + want: "Mgmtclass test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_MgmtClassCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "copy", "--name", "mgmtclass-to-copy", "--newname", "copied-mgmtclass"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeMgmtClass(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetMgmtClass(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_MgmtClassEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "edit", "--name", "test-mgmtclass-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedMgmtClass, err := Client.GetMgmtClass(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedMgmtClass.Comment != "testcomment" { + t.Fatal("mgmtclass update wasn't successful") + } + }) + } +} + +func Test_MgmtClassFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "find", "--name", "test-mgmtclass-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + mgmtclassName := "test-mgmtclass-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, mgmtclassName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMgmtClass(Client, mgmtclassName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, mgmtclassName) { + fmt.Println(stdoutString) + t.Fatal("mgmtclass not successfully found") + } + }) + } +} + +func Test_MgmtClassListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "list"}}, + want: "mgmtclasses:", + 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 + cobbler.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("mgmtclass list marker not located in output") + } + }) + } +} + +func Test_MgmtClassRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "remove", "--name", "test-mgmtclass-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createMgmtClass(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("mgmtclass", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("mgmtclass not successfully removed") + } + }) + } +} + +func Test_MgmtClassRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "rename", "--name", "test-mgmtclass-rename", "--newname", "test-mgmtclass-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + mgmtclassName := "test-mgmtclass-rename" + newMgmtClassName := "test-mgmtclass-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, newMgmtClassName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMgmtClass(Client, mgmtclassName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("mgmtclass", mgmtclassName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("mgmtclass not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("mgmtclass", newMgmtClassName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("mgmtclass not successfully renamed (new name not present)") + } + }) + } +} + +func Test_MgmtClassReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "mgmtclass", "report", "--name", "test-mgmtclass-report"}}, + want: ": test-mgmtclass-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + mgmtclassName := "test-mgmtclass-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeMgmtClass(Client, mgmtclassName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createMgmtClass(Client, mgmtclassName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/mkloaders_test.go b/cmd/mkloaders_test.go new file mode 100644 index 0000000..e330ef5 --- /dev/null +++ b/cmd/mkloaders_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_MkLoaders(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "mkloaders"}) + 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, "Event ID:") { + fmt.Println(stdoutString) + t.Fatal("No Event ID present") + } +} diff --git a/cmd/package_test.go b/cmd/package_test.go new file mode 100644 index 0000000..3d55d93 --- /dev/null +++ b/cmd/package_test.go @@ -0,0 +1,454 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createPackage(client cobbler.Client, name string) (*cobbler.Package, error) { + linuxpackage := cobbler.NewPackage() + linuxpackage.Name = name + return client.CreatePackage(linuxpackage) +} + +func removePackage(client cobbler.Client, name string) error { + return client.DeletePackage(name) +} + +func Test_PackageAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "add", "--name", "test-plain"}}, + want: "Package test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_PackageCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "copy", "--name", "package-to-copy", "--newname", "copied-package"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removePackage(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createPackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetPackage(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_PackageEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "edit", "--name", "test-package-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createPackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedPackage, err := Client.GetPackage(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedPackage.Comment != "testcomment" { + t.Fatal("package update wasn't successful") + } + }) + } +} + +func Test_PackageFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "find", "--name", "test-package-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + packageName := "test-package-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, packageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createPackage(Client, packageName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, packageName) { + fmt.Println(stdoutString) + t.Fatal("package not successfully found") + } + }) + } +} + +func Test_PackageListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "list"}}, + want: "packages:", + 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 + cobbler.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("package list marker not located in output") + } + }) + } +} + +func Test_PackageRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "remove", "--name", "test-package-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createPackage(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("package", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("package not successfully removed") + } + }) + } +} + +func Test_PackageRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "rename", "--name", "test-package-rename", "--newname", "test-package-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + packageName := "test-package-rename" + newPackageName := "test-package-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, newPackageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createPackage(Client, packageName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("package", packageName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("package not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("package", newPackageName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("package not successfully renamed (new name not present)") + } + }) + } +} + +func Test_PackageReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "package", "report", "--name", "test-package-report"}}, + want: ": test-package-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + packageName := "test-package-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removePackage(Client, packageName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createPackage(Client, packageName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/profile_test.go b/cmd/profile_test.go new file mode 100644 index 0000000..31d7993 --- /dev/null +++ b/cmd/profile_test.go @@ -0,0 +1,455 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createProfile(client cobbler.Client, name string) (*cobbler.Profile, error) { + profile := cobbler.NewProfile() + profile.Name = name + profile.Distro = "Ubuntu-20.04-x86_64" + return client.CreateProfile(profile) +} + +func removeProfile(client cobbler.Client, name string) error { + return client.DeleteProfile(name) +} + +func Test_ProfileAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "add", "--name", "test-plain", "--distro", "Ubuntu-20.04-x86_64"}}, + want: "Profile test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_ProfileCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "copy", "--name", "profile-to-copy", "--newname", "copied-profile"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeProfile(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetProfile(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_ProfileEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "edit", "--name", "test-profile-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedProfile, err := Client.GetProfile(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedProfile.Comment != "testcomment" { + t.Fatal("profile update wasn't successful") + } + }) + } +} + +func Test_ProfileFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "find", "--name", "test-profile-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + profileName := "test-profile-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, profileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createProfile(Client, profileName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, profileName) { + fmt.Println(stdoutString) + t.Fatal("profile not successfully found") + } + }) + } +} + +func Test_ProfileListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "list"}}, + want: "profiles:", + 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 + cobbler.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("profile list marker not located in output") + } + }) + } +} + +func Test_ProfileRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "remove", "--name", "test-profile-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createProfile(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("profile", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("profile not successfully removed") + } + }) + } +} + +func Test_ProfileRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "rename", "--name", "test-profile-rename", "--newname", "test-profile-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + profileName := "test-profile-rename" + newProfileName := "test-profile-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, newProfileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createProfile(Client, profileName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("profile", profileName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("profile not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("profile", newProfileName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("profile not successfully renamed (new name not present)") + } + }) + } +} + +func Test_ProfileReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "profile", "report", "--name", "test-profile-report"}}, + want: ": test-profile-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + profileName := "test-profile-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeProfile(Client, profileName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createProfile(Client, profileName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/replicate_test.go b/cmd/replicate_test.go new file mode 100644 index 0000000..2992646 --- /dev/null +++ b/cmd/replicate_test.go @@ -0,0 +1,58 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ReplicateCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "replicate"}}, + 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") + } + }) + } +} diff --git a/cmd/repo_test.go b/cmd/repo_test.go new file mode 100644 index 0000000..f767d94 --- /dev/null +++ b/cmd/repo_test.go @@ -0,0 +1,454 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createRepo(client cobbler.Client, name string) (*cobbler.Repo, error) { + repo := cobbler.NewRepo() + repo.Name = name + return client.CreateRepo(repo) +} + +func removeRepo(client cobbler.Client, name string) error { + return client.DeleteRepo(name) +} + +func Test_RepoAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "add", "--name", "test-plain"}}, + want: "Repo test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_RepoCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "copy", "--name", "repo-to-copy", "--newname", "copied-repo"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeRepo(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetRepo(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_RepoEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "edit", "--name", "test-repo-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedRepo, err := Client.GetRepo(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedRepo.Comment != "testcomment" { + t.Fatal("repo update wasn't successful") + } + }) + } +} + +func Test_RepoFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "find", "--name", "test-repo-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + repoName := "test-repo-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, repoName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createRepo(Client, repoName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, repoName) { + fmt.Println(stdoutString) + t.Fatal("repo not successfully found") + } + }) + } +} + +func Test_RepoListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "list"}}, + want: "repos:", + 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 + cobbler.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("repo list marker not located in output") + } + }) + } +} + +func Test_RepoRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "remove", "--name", "test-repo-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createRepo(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("repo", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("repo not successfully removed") + } + }) + } +} + +func Test_RepoRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "rename", "--name", "test-repo-rename", "--newname", "test-repo-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + repoName := "test-repo-rename" + newRepoName := "test-repo-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, newRepoName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createRepo(Client, repoName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("repo", repoName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("repo not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("repo", newRepoName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("repo not successfully renamed (new name not present)") + } + }) + } +} + +func Test_RepoReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "repo", "report", "--name", "test-repo-report"}}, + want: ": test-repo-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + repoName := "test-repo-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeRepo(Client, repoName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createRepo(Client, repoName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/report_test.go b/cmd/report_test.go new file mode 100644 index 0000000..0ef2bb3 --- /dev/null +++ b/cmd/report_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ReportCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "report"}) + 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, "distros:") && strings.Contains(stdoutString, "profiles")) { + fmt.Println(stdoutString) + t.Fatal("no heading for distros and profiles present") + } +} diff --git a/cmd/reposync_test.go b/cmd/reposync_test.go new file mode 100644 index 0000000..2e1bdeb --- /dev/null +++ b/cmd/reposync_test.go @@ -0,0 +1,70 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ReposyncCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "reposync"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "tries", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "reposync", "--tries", "3"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "nofail", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "reposync", "--no-fail"}}, + 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") + } + }) + } +} diff --git a/cmd/setting_test.go b/cmd/setting_test.go new file mode 100644 index 0000000..29744fe --- /dev/null +++ b/cmd/setting_test.go @@ -0,0 +1,60 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_SettingEditCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "setting", "edit"}) + stdout := bytes.NewBufferString("") + stderr := bytes.NewBufferString("") + rootCmd.SetOut(stdout) + rootCmd.SetErr(stderr) + + // Act + err := rootCmd.Execute() + + // Assert + if err == nil { + t.Fatal("expected error, got none") + } + if err.Error() != "dynamic settings are turned off server-side" { + t.Fatalf("expected dynamic settings are to be turned off server-side, got %s", err.Error()) + } +} + +func Test_SettingReportCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "setting", "report"}) + 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, "scm_track_enabled") { + fmt.Println(stdoutString) + t.Fatal("Expected setting couldn't be found") + } +} diff --git a/cmd/signature_test.go b/cmd/signature_test.go new file mode 100644 index 0000000..fbd07eb --- /dev/null +++ b/cmd/signature_test.go @@ -0,0 +1,92 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_SignatureReloadCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "signature", "reload"}) + 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, "This functionality cannot be used in the new CLI") { + fmt.Println(stdoutString) + t.Fatal("No missing feature message present") + } +} + +func Test_SignatureReportCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "signature", "report"}) + 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, "Currently loaded signatures") { + fmt.Println(stdoutString) + t.Fatal("No report header present") + } +} + +func Test_SignatureUpdateCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "signature", "update"}) + 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, "Event ID:") { + fmt.Println(stdoutString) + t.Fatal("No Event ID present") + } +} diff --git a/cmd/sync_test.go b/cmd/sync_test.go new file mode 100644 index 0000000..44028be --- /dev/null +++ b/cmd/sync_test.go @@ -0,0 +1,86 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" + "time" +) + +func Test_SyncCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "sync"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "dns", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "sync", "--dns"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "dhcp", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "sync", "--dhcp"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "dhcpdns", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "sync", "--dns", "--dhcp"}}, + want: "Event ID:", + wantErr: false, + }, + { + name: "systems", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "sync", "--systems", "a.b.c,a.d.c"}}, + 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") + } + + // Cleanup - Sleep after each test to let dhcpd restart properly + time.Sleep(1 * time.Second) + }) + } +} diff --git a/cmd/system_test.go b/cmd/system_test.go new file mode 100644 index 0000000..6264d57 --- /dev/null +++ b/cmd/system_test.go @@ -0,0 +1,455 @@ +package cmd + +import ( + "bytes" + "fmt" + cobbler "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func createSystem(client cobbler.Client, name string) (*cobbler.System, error) { + system := cobbler.NewSystem() + system.Name = name + system.Profile = "Ubuntu-20.04-x86_64" + return client.CreateSystem(system) +} + +func removeSystem(client cobbler.Client, name string) error { + return client.DeleteSystem(name) +} + +func Test_SystemAddCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "add", "--name", "test-plain", "--profile", "Ubuntu-20.04-x86_64"}}, + want: "System test-plain created", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // 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 + cobbler.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("Item creation message missing") + } + }) + } +} + +func Test_SystemCopyCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "copy", "--name", "system-to-copy", "--newname", "copied-system"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + cleanupErr = removeSystem(Client, tt.args.command[7]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + _, err = Client.GetSystem(tt.args.command[7], false, false) + cobbler.FailOnError(t, err) + }) + } +} + +func Test_SystemEditCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "edit", "--name", "test-system-edit", "--comment", "testcomment"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + updatedSystem, err := Client.GetSystem(tt.args.command[5], false, false) + cobbler.FailOnError(t, err) + if updatedSystem.Comment != "testcomment" { + t.Fatal("system update wasn't successful") + } + }) + } +} + +func Test_SystemFindCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "find", "--name", "test-system-find"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + systemName := "test-system-find" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, systemName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createSystem(Client, systemName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + stdoutBytes, err := io.ReadAll(stdout) + if err != nil { + t.Fatal(err) + } + stdoutString := string(stdoutBytes) + if !strings.Contains(stdoutString, systemName) { + fmt.Println(stdoutString) + t.Fatal("system not successfully found") + } + }) + } +} + +func Test_SystemListCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "list"}}, + want: "systems:", + 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 + cobbler.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("system list marker not located in output") + } + }) + } +} + +func Test_SystemRemoveCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "remove", "--name", "test-system-remove"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Arrange + setupClient(t) + _, err := createSystem(Client, tt.args.command[5]) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + result, err := Client.HasItem("system", tt.args.command[5]) + cobbler.FailOnError(t, err) + if result { + // A missing item means we get "false", as such we error when we find an item. + t.Fatal("system not successfully removed") + } + }) + } +} + +func Test_SystemRenameCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "rename", "--name", "test-system-rename", "--newname", "test-system-renamed"}}, + want: "Event ID:", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + systemName := "test-system-rename" + newSystemName := "test-system-renamed" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, newSystemName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createSystem(Client, systemName) + cobbler.FailOnError(t, err) + 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 + cobbler.FailOnError(t, err) + FailOnNonEmptyStream(t, stderr) + FailOnNonEmptyStream(t, stdout) + resultOldName, err := Client.HasItem("system", systemName) + cobbler.FailOnError(t, err) + if resultOldName { + t.Fatal("system not successfully renamed (old name present)") + } + resultNewName, err := Client.HasItem("system", newSystemName) + cobbler.FailOnError(t, err) + if !resultNewName { + t.Fatal("system not successfully renamed (new name not present)") + } + }) + } +} + +func Test_SystemReportCmd(t *testing.T) { + type args struct { + command []string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "plain", + args: args{command: []string{"--config", "../testing/.cobbler.yaml", "system", "report", "--name", "test-system-report"}}, + want: ": test-system-report", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Cleanup + systemName := "test-system-report" + var err error + defer func() { + // Client is initialized since this is the cleanup + cleanupErr := removeSystem(Client, systemName) + cobbler.FailOnError(t, cleanupErr) + }() + // Arrange + setupClient(t) + _, err = createSystem(Client, systemName) + cobbler.FailOnError(t, err) + 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 + cobbler.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") + } + }) + } +} diff --git a/cmd/testing.go b/cmd/testing.go new file mode 100644 index 0000000..3ecb48b --- /dev/null +++ b/cmd/testing.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "bytes" + cobbler "github.com/cobbler/cobblerclient" + "testing" +) + +func setupClient(t *testing.T) { + cfgFile = "../testing/.cobbler.yaml" + initConfig() + err := generateCobblerClient() + cobbler.FailOnError(t, err) +} + +func FailOnNonEmptyStream(t *testing.T, buffer *bytes.Buffer) { + if buffer.Available() > 0 { + t.Fatal("stream wasn't empty!") + } +} diff --git a/cmd/utils_test.go b/cmd/utils_test.go index c743d63..a82235f 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -1,7 +1,6 @@ package cmd import ( - "fmt" "reflect" "testing" "time" @@ -26,7 +25,6 @@ func Test_covertFloatToTime(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := covertFloatToUtcTime(tt.args.t) - fmt.Println(got) if (err != nil) != tt.wantErr { t.Errorf("covertFloatToTime() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/cmd/validateAutoinstalls_test.go b/cmd/validateAutoinstalls_test.go new file mode 100644 index 0000000..d80f24c --- /dev/null +++ b/cmd/validateAutoinstalls_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_ValidateAutoinstallsCmd(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "validate-autoinstalls"}) + 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, "Event ID:") { + fmt.Println(stdoutString) + t.Fatal("No Event ID present") + } +} diff --git a/cmd/version_test.go b/cmd/version_test.go new file mode 100644 index 0000000..ac86d73 --- /dev/null +++ b/cmd/version_test.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/cobbler/cobblerclient" + "github.com/spf13/cobra" + "io" + "strings" + "testing" +) + +func Test_VersionCommand(t *testing.T) { + // Arrange + cobra.OnInitialize(initConfig, setupLogger) + rootCmd := NewRootCmd() + rootCmd.SetArgs([]string{"--config", "../testing/.cobbler.yaml", "version"}) + 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, "source: ?, ?") { + fmt.Println(stdoutString) + t.Fatal("CLI version not part of the return string") + } +} diff --git a/testing/.cobbler.yaml b/testing/.cobbler.yaml new file mode 100644 index 0000000..6531712 --- /dev/null +++ b/testing/.cobbler.yaml @@ -0,0 +1,3 @@ +server_url: "http://127.0.0.1:8081/cobbler_api" +server_username: "cobbler" +server_password: "cobbler" diff --git a/testing/compose.yml b/testing/compose.yml new file mode 100644 index 0000000..f02d3f3 --- /dev/null +++ b/testing/compose.yml @@ -0,0 +1,17 @@ +services: + cobbler: + image: cobbler-dev + container_name: cobbler-dev + privileged: true # Required for Cobbler 3.3.2 and newer + volumes: + - ./cobbler_source:/code + - ../extracted_iso_image:/extracted_iso_image + ports: + - 8081:80 + # We chmod the code, otherwise some files are read-only and cannot be cleaned up: + command: bash -c " + /code/docker/develop/scripts/setup-supervisor.sh && + chmod -R o+w /code && + cobbler import --name Ubuntu-20.04 --breed ubuntu --path /extracted_iso_image/ && + tail -F /dev/null + " diff --git a/testing/start.sh b/testing/start.sh new file mode 100755 index 0000000..1d75463 --- /dev/null +++ b/testing/start.sh @@ -0,0 +1,70 @@ +#! /bin/bash + +# Requires xorriso (sudo apt-get install -y xorriso, sudo yum install xorriso -y, or sudo zypper install -y xorriso) +if [ -z "$1" ] + then + echo "No cobbler server url supplied" +fi + +cobbler_commit=df356046f3cf27be62a61001b982d5983800cfd9 # 3.3.6 as of 2024-10-09 +cobbler_branch=release33 +iso_url=https://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04/release/ubuntu-20.04.1-legacy-server-amd64.iso +iso_os=ubuntu +valid_iso_checksum=00a9d46306fbe9beb3581853a289490bc231c51f +iso_filename=$(echo ${iso_url##*/}) +valid_extracted_iso_checksum=dd0b3148e1f071fb86aee4b0395fd63b +valid_git_checksum=6c9511b26946dd3f1f072b9f40eaeccf # master as of 4/2/2022 + +[ -d "./testing/cobbler_source" ] && git_checksum=$(find ./testing/cobbler_source/ -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') +if [ -d "./testing/cobbler_source" ] && [ $git_checksum == $valid_git_checksum ]; then + echo "Cobbler code already cloned and the correct version is checked out" +else + rm -rf ./testing/cobbler_source + git clone --shallow-since="2021-09-01" https://github.com/cobbler/cobbler.git -b $cobbler_branch testing/cobbler_source + cd ./testing/cobbler_source + printf "Changing to version of Cobbler being tested.\n\n" + git checkout $cobbler_commit > /dev/null 2>&1 + rm -rf .git # remove .git dir so the checksum is consistent + cd - +fi + +echo $(pwd) +if [ -f "$iso_filename" ] && [ $(sha1sum $iso_filename | awk '{print $1}') == "$valid_iso_checksum" ]; then + echo "ISO already downloaded" +else + rm $iso_filename + wget $iso_url +fi + +extracted_iso_checksum=$(find extracted_iso_image -type f -exec md5sum {} \; | sort -k 2 | md5sum | awk '{print $1}') +if [ -d "extracted_iso_image" ] && [ $extracted_iso_checksum == $valid_extracted_iso_checksum ]; then + echo "ISO already extracted" +else + xorriso -osirrox on -indev $iso_filename -extract / extracted_iso_image +fi + +docker build -f ./testing/cobbler_source/docker/develop/develop.dockerfile -t cobbler-dev . +docker compose -f testing/compose.yml up -d + +SERVER_URL=$1 +printf "### Waiting for Cobbler to become available on ${SERVER_URL} \n\n" + +attempt_counter=0 +max_attempts=48 + +until $(curl --connect-timeout 1 --output /dev/null --silent ${SERVER_URL}); do + if [ ${attempt_counter} -eq ${max_attempts} ];then + echo "Max attempts reached" + # Debug logs + docker compose -f ./testing/compose.yml logs + exit 1 + fi + + attempt_counter=$(($attempt_counter+1)) + sleep 5 +done + +# Sleep 10 seconds to let the "cobbler import" succeed +sleep 10 + +docker compose -f testing/compose.yml logs \ No newline at end of file