Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Version 8.0.0 #162

Merged
merged 34 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8b0a22d
Code refactoring
andyone Oct 12, 2023
9fc220c
Improve support info collecting
andyone Oct 12, 2023
cc041f2
Add support of symlinks to bibop-massive script
andyone Oct 12, 2023
431b498
Dependencies update
andyone Oct 12, 2023
7fd9531
Add better recipes filtering to bibop-massive script
andyone Oct 13, 2023
2e60262
Improve install/uninstall actions in bibop-massive script
andyone Oct 14, 2023
9a6efbc
Improve install/uninstall actions in bibop-massive script
andyone Oct 14, 2023
0a127ca
Migrate from goterm/term to creack/pty
andyone Oct 15, 2023
d4ddae0
Bump github.com/essentialkaos/ek/v12 from 12.80.0 to 12.82.0
dependabot[bot] Oct 17, 2023
46204c7
Merge pull request #163 from essentialkaos/dependabot/go_modules/deve…
andyone Oct 17, 2023
48cef63
Improve verbose version info
andyone Oct 17, 2023
9e2e3a4
Merge branch 'develop' of github.com:essentialkaos/bibop into develop
andyone Oct 17, 2023
4c5ea83
Code refactoring
andyone Oct 17, 2023
d4b4dbd
Code refactoring
andyone Oct 17, 2023
b5929a7
Bump github.com/essentialkaos/ek/v12 from 12.82.0 to 12.83.1
dependabot[bot] Oct 24, 2023
6b19cd2
Merge pull request #165 from essentialkaos/dependabot/go_modules/deve…
andyone Oct 25, 2023
20496ce
Get binding suffix from python
andyone Oct 26, 2023
761ae80
Improve reading command output
andyone Oct 28, 2023
b0bedd8
Add readme for scripts
andyone Oct 28, 2023
8454c2e
Improve CI workflow
andyone Oct 28, 2023
9be2f8e
Use terminal window 256x80 for all commands
andyone Oct 29, 2023
9325d0d
Improve data sanitization
andyone Oct 29, 2023
060b27c
Bump github.com/creack/pty from 1.1.18 to 1.1.20
dependabot[bot] Oct 30, 2023
3c3f1b8
Merge pull request #166 from essentialkaos/dependabot/go_modules/deve…
andyone Oct 30, 2023
844fdd8
Add 'template' action
andyone Oct 30, 2023
d6b8293
Code refactoring
andyone Oct 31, 2023
3032b77
Add --pause/-P option for pause between executing commands
andyone Oct 31, 2023
9dacafa
Update usage demo
andyone Oct 31, 2023
fa7e25d
Improve cookbook
andyone Oct 31, 2023
32c06cb
Improve README
andyone Nov 1, 2023
6add8a1
Dependencies update
andyone Nov 1, 2023
c0c3350
Improve recipe validation
andyone Nov 1, 2023
364995d
Improve recipe validation
andyone Nov 1, 2023
11cd8fe
Update usage demo
andyone Nov 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
- name: Check scripts with Shellcheck
uses: essentialkaos/shellcheck-action@v1
with:
files: scripts/*
files: scripts/bibop-dep scripts/bibop-docker scripts/bibop-entrypoint scripts/bibop-libtest-gen scripts/bibop-linked scripts/bibop-massive scripts/bibop-multi-check scripts/bibop-so-exported

Hadolint:
name: Hadolint
Expand Down
68 changes: 68 additions & 0 deletions COOKBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [Common](#common)
* [`exit`](#exit)
* [`wait`](#wait)
* [`template`](#template)
* [Input/Output](#inputoutput)
* [`expect`](#expect)
* [`print`](#print)
Expand Down Expand Up @@ -490,6 +491,71 @@ command "echo 'ABCD'" "Simple echo command"

<a href="#"><img src="https://gh.kaos.st/separator.svg"/></a>

##### `template`

Creates a file from a template. If file already exists, it will be rewritten with the same UID, GID and mode.

▲ _Note that 'template' action will not automatically backup the destination file if it already exists (use `backup` and `backup-restore` actions to preserve the original file). Also, the created file will remain after tests execution if it was created outside the working directory._

You can use the following methods in your templates:

- `Var "name"` - get variable value;
- `Is "name" "value"` - compare variable value.

Simple example:

```
# Sysconfig for postgresql service

PG_ENGINE=""
PG_POSTMASTER=""
{{ if not .Is "data_dir" "" }}
PG_DATA="{{ .Var "data_dir" }}/db"
{{ else }}
PG_DATA=""
{{ end }}
PG_LOG=""
PG_UPLOG=""
PG_SOCKET_DIR=""
TIMEOUT=""
DISABLE_AUTO_NUMA=""
```

**Syntax:** `template <source> <dest> [file-mode]`

**Arguments:**

* `source` - Path to template file (_String_)
* `dest` - Destination path (_String_)
* `file-mode` - Destination file mode (_Integer_) [Optional | 644]

**Negative form:** No

**Example:**

```yang
command "-" "Create configuration file"
template app.template /etc/myapp.conf
```

```yang
command "-" "Create configuration file"
template app.template /etc/myapp.conf 640
```

```yang
command "-" "Replace configuration file"
backup /etc/myapp.conf
template app.template /etc/myapp.conf 640

...

command "-" "Restore original configuration file"
backup-restore /etc/myapp.conf
```

<a href="#"><img src="https://gh.kaos.st/separator.svg"/></a>

#### Input/Output

Be aware that the output store limited to 2 Mb of data for each stream (`stdout` _and_ `stderr`). So if command generates lots of output data, it better to use `expect` action to working with the output.
Expand Down Expand Up @@ -563,6 +629,8 @@ command "echo 'ABCD'" "Simple echo command"
wait-output 10.0
```

<a href="#"><img src="https://gh.kaos.st/separator.svg"/></a>

##### `output-match`

Checks output with given [regular expression](https://en.wikipedia.org/wiki/Regular_expression).
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

<br/>

`bibop` is a utility for testing command-line tools and daemons. Initially, this utility was created for testing packages from [ESSENTIAL KAOS Public Repository](https://pkgs.kaos.st).
`bibop` is a utility for testing command-line tools, packages and daemons. Initially, this utility was created for testing packages from [ESSENTIAL KAOS Public Repository](https://kaos.sh/kaos-repo).

Information about bibop recipe syntax you can find in our [cookbook](COOKBOOK.md).

### Usage demo

[![demo](https://gh.kaos.st/bibop-600.gif)](#usage-demo)
https://github.com/essentialkaos/bibop/assets/182020/c63dc147-fa44-40df-92e2-12f530c411af

### Installation

Expand Down Expand Up @@ -99,7 +99,8 @@ Usage: bibop {options} recipe
Options

--dry-run, -D Parse and validate recipe
--extra, -X Print the last lines from command output if action was failed
--extra, -X lines Number of output lines for failed action (default: 10)
--pause, -P duration Pause between commands in seconds
--list-packages, -L List required packages
--list-packages-flat, -L1 List required packages in one line (useful for scripts)
--variables, -V List recipe variables
Expand Down Expand Up @@ -128,6 +129,12 @@ Examples
bibop app.recipe --tag init,service
Run tests from app.recipe and execute commands with tags init and service

bibop app.recipe --extra
Run tests from app.recipe and print the last 10 lines from command output if action was failed

bibop app.recipe --extra=50
Run tests from app.recipe and print the last 50 lines from command output if action was failed

bibop app.recipe --format json 1> ~/results/app.json
Run tests from app.recipe and save result in JSON format

Expand Down
7 changes: 4 additions & 3 deletions action/auxi.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type OutputContainer struct {
// ////////////////////////////////////////////////////////////////////////////////// //

// escapeCharRegex is regexp for searching escape characters
var escapeCharRegex = regexp.MustCompile(`\x1b\[[0-9\;]+m`)
var escapeCharRegex = regexp.MustCompile("[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))")

// ////////////////////////////////////////////////////////////////////////////////// //

Expand Down Expand Up @@ -101,11 +101,11 @@ func (c *OutputContainer) Tail(lines int) string {
}

if line == lines {
return strings.TrimRight(string(data[i+1:]), " \n\r")
return strings.Trim(string(data[i+1:]), " \n\r")
}
}

return strings.TrimRight(string(data), " \n\r")
return strings.Trim(string(data), " \n\r")
}

// IsEmpty returns true if container is empty
Expand Down Expand Up @@ -156,5 +156,6 @@ func fmtValue(v string) string {

// sanitizeData removes escape characters
func sanitizeData(data []byte) []byte {
data = bytes.ReplaceAll(data, []byte("\r"), nil)
return escapeCharRegex.ReplaceAll(data, nil)
}
2 changes: 1 addition & 1 deletion action/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Wait(action *recipe.Action) error {
return err
}

durSec = mathutil.BetweenF64(durSec, 0.01, 3600.0)
durSec = mathutil.Between(durSec, 0.01, 3600.0)

time.Sleep(timeutil.SecondsToDuration(durSec))

Expand Down
2 changes: 1 addition & 1 deletion action/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ func Cleanup(action *recipe.Action) error {
err = os.RemoveAll(obj)

if err != nil {
return fmt.Errorf("Can't remove object %q: %v", err)
return fmt.Errorf("Can't remove object %q: %v", obj, err)
}
}

Expand Down
13 changes: 2 additions & 11 deletions action/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,7 @@ func HTTPSetHeader(action *recipe.Action) error {

// ////////////////////////////////////////////////////////////////////////////////// //

// isHTTPMethodSupported returns true if HTTP method is supported
func isHTTPMethodSupported(method string) bool {
switch method {
case req.GET, req.POST, req.DELETE, req.PUT, req.PATCH, req.HEAD:
return true
}

return false
}

// checkRequestData checks request data
func checkRequestData(method, payload string) error {
switch method {
case req.GET, req.POST, req.DELETE, req.PUT, req.PATCH, req.HEAD:
Expand Down Expand Up @@ -353,6 +344,6 @@ func makeHTTPRequest(action *recipe.Action, method, url, payload string) *req.Re

// parseJSONQuery converts json query to slice
func parseJSONQuery(q string) []string {
q = strings.Replace(q, "[", ".[", -1)
q = strings.ReplaceAll(q, "[", ".[")
return strings.Split(q, ".")
}
4 changes: 2 additions & 2 deletions action/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func Expect(action *recipe.Action, output *OutputContainer) error {
}

start := time.Now()
timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

for range time.NewTicker(_DATA_READ_PERIOD).C {
Expand Down Expand Up @@ -98,7 +98,7 @@ func Input(action *recipe.Action, input *os.File, output *OutputContainer) error
}

if !strings.HasSuffix(text, "\n") {
text = text + "\n"
text += "\n"
}

output.Purge()
Expand Down
2 changes: 1 addition & 1 deletion action/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func WaitService(action *recipe.Action) error {
}

start := time.Now()
timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

for range time.NewTicker(time.Second / 2).C {
Expand Down
8 changes: 4 additions & 4 deletions action/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func WaitPID(action *recipe.Action) error {
}

start := time.Now()
timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

for range time.NewTicker(25 * time.Millisecond).C {
Expand Down Expand Up @@ -147,7 +147,7 @@ func WaitFS(action *recipe.Action) error {
}

start := time.Now()
timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

for range time.NewTicker(25 * time.Millisecond).C {
Expand Down Expand Up @@ -203,7 +203,7 @@ func WaitConnect(action *recipe.Action) error {
}

start := time.Now()
timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

for range time.NewTicker(25 * time.Millisecond).C {
Expand Down Expand Up @@ -264,7 +264,7 @@ func Connect(action *recipe.Action) error {
timeout = 1.0
}

timeout = mathutil.BetweenF64(timeout, 0.01, 3600.0)
timeout = mathutil.Between(timeout, 0.01, 3600.0)
timeoutDur := timeutil.SecondsToDuration(timeout)

conn, err := net.DialTimeout(network, address, timeoutDur)
Expand Down
114 changes: 114 additions & 0 deletions action/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package action

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"fmt"
"os"
"strconv"
"text/template"

"github.com/essentialkaos/bibop/recipe"
)

// ////////////////////////////////////////////////////////////////////////////////// //

// varWrapper is a recipe wrapper for accessing variables
type varWrapper struct {
r *recipe.Recipe
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Template is action processor for "template"
func Template(action *recipe.Action) error {
mode := uint64(0644)
source, err := action.GetS(0)

if err != nil {
return err
}

dest, err := action.GetS(1)

if err != nil {
return err
}

isSafePath, err := checkPathSafety(action.Command.Recipe, source)

if err != nil {
return err
}

if !isSafePath {
return fmt.Errorf("Action uses unsafe path (%s)", source)
}

isSafePath, err = checkPathSafety(action.Command.Recipe, dest)

if err != nil {
return err
}

if !isSafePath {
return fmt.Errorf("Action uses unsafe path (%s)", dest)
}

if action.Has(2) {
modeStr, _ := action.GetS(1)
mode, err = strconv.ParseUint(modeStr, 8, 32)

if err != nil {
return err
}
}

tmplData, err := os.ReadFile(source)

if err != nil {
fmt.Errorf("Can't read template %q: %v", source, err)
}

tmpl, err := template.New("").Parse(string(tmplData))

if err != nil {
return fmt.Errorf("Can't parse template %q: %v", source, err)
}

fd, err := os.OpenFile(dest, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.FileMode(mode))

if err != nil {
return fmt.Errorf("Can't save template data into %q: %v", dest, err)
}

defer fd.Close()

vw := &varWrapper{action.Command.Recipe}
err = tmpl.Execute(fd, vw)

if err != nil {
return fmt.Errorf("Can't render template %q: %v", source, err)
}

return nil
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Var returns variable value
func (vw *varWrapper) Var(name string) string {
return vw.r.GetVariable(name, true)
}

// Is compares variable value
func (vw *varWrapper) Is(name, value string) bool {
return vw.r.GetVariable(name, true) == value
}

// ////////////////////////////////////////////////////////////////////////////////// //
2 changes: 1 addition & 1 deletion cli/barcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func getPackagesInfo(pkgs []string) ([]byte, error) {

// getRPMPackagesInfo returns info about installed packages from rpm
func getRPMPackagesInfo(pkgs []string) ([]byte, error) {
cmd := exec.Command("rpm", "-q", "--queryformat", "%{FILEMD5S}\n")
cmd := exec.Command("rpm", "-q", "--qf", "%{pkgid}\n")
cmd.Env = []string{"LC_ALL=C"}
cmd.Args = append(cmd.Args, pkgs...)

Expand Down
Loading
Loading