Skip to content

Commit

Permalink
Merge pull request #14 from FMotalleb/cleanup-optimize
Browse files Browse the repository at this point in the history
Major: Tests/Optimizition/Rename
  • Loading branch information
FMotalleb authored Jun 16, 2024
2 parents 5a9fae3 + 74ec72e commit fc2ac68
Show file tree
Hide file tree
Showing 34 changed files with 1,324 additions and 249 deletions.
4 changes: 2 additions & 2 deletions abstraction/scheduler.go → abstraction/event.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Package abstraction must contain only interfaces and abstract layers of modules
package abstraction

// Scheduler is an object that can be executed using a execute method and stopped using cancel method
type Scheduler interface {
// Event is an object that can be executed using a execute method and stopped using cancel method
type Event interface {
BuildTickChannel() <-chan any
Cancel()
}
8 changes: 4 additions & 4 deletions config.doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ jobs:
# # Body of post request (can be a json object)
# data:
# key: value
schedulers:
events:
- on-init: true
# Schedulers can be defined using either a cron expression or an interval, but not both simultaneously.
# However, you can combine multiple cron expressions and intervals within the same scheduler.
# events can be defined using either a cron expression or an interval, but not both simultaneously.
# However, you can combine multiple cron expressions and intervals within the same events list.

# The cron scheduler allows you to specify schedules down to the second level of precision using cron expressions.
# The cron event allows you to specify schedules down to the second level of precision using cron expressions.
- cron: "@yearly"
# Intervals can be defined using human-readable formats.
# For example, '10h' represents 10 hours, '10m' represents 10 minutes, and '10m15s' represents every 10 minutes and 15 seconds.
Expand Down
55 changes: 1 addition & 54 deletions config.example.yaml
Original file line number Diff line number Diff line change
@@ -1,72 +1,19 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/FMotalleb/crontab-go/main/schema.json
#TODO: unix/tcp socket controller
#TODO: prometheus exporter

jobs:
# Jobs can be assigned a unique name, which will be included in log messages for easier debugging.
- name: Test Job
# Description is reserved for the future
description: Sample of a single job
# Jobs can be disabled explicitly instead of commenting/removing the job
# disabled: true
tasks:
# This line specifies the actual command to be executed.
- command: echo $(whoami)
# This setting determines the number of times the task will be retried if it fails
# A failure is defined by either a non-zero exit code for commands or a status code of 400 or higher for HTTP requests.
retries: 3
# This specifies the delay between retries.
retry-delay: 1s
# This sets a maximum time limit for the task to complete.
# If the task exceeds 15 seconds, it will be considered failed and stopped (command) or canceled (http requests)
timeout: 15s
user: root
# # This defines the working directory for the command.
# working-dir: C://
# This section allows you to set environment variables that will be available to the command during execution.
# `SHELL` and `SHELL_ARGS` can be used to change this commands shell environment
# env:
# DB_HOST: 10.0.0.5

# # A simple get request
# - get: https://example.com/get
# # headers of request `map[string]string`
# headers:
# - "Accepts": "Application/Json"

# # A simple post request example
# - post: https://example.com/post
# # headers of request `map[string]string`
# headers:
# - "Accepts": "Application/Json"
# # Body of post request (can be a json object)
# data:
# key: value
schedulers:
events:
- on-init: true
# Schedulers can be defined using either a cron expression or an interval, but not both simultaneously.
# However, you can combine multiple cron expressions and intervals within the same scheduler.

# The cron scheduler allows you to specify schedules down to the second level of precision using cron expressions.
- cron: "@yearly"
# Intervals can be defined using human-readable formats.
# For example, '10h' represents 10 hours, '10m' represents 10 minutes, and '10m15s' represents every 10 minutes and 15 seconds.
# You can use units of hours (h), minutes (m), seconds (s), milliseconds (ms), and nanoseconds (ns) to define your intervals.
- interval: 10m10s
hooks:
# Hooks are essentially tasks like those used in jobs, but they do not support nested hooks.
# Additionally, errors or completion status of hooks are not directly managed by the system.
# Instead, they are logged for informational purposes.

# Every command within a job triggers its own set of hooks.
# For instance, a job with two tasks and three 'done' hooks will execute a total of six hooks (if done)
# during a single run: three for each task.

# The 'done' hook will be triggered for HTTP requests with status codes below 400,
# indicating successful completion.
# For commands, the 'done' hook will be triggered if the exit code is 0,
# signifying successful execution.
# otherwise the `failed` hooks will be executed
done:
- command: echo Ok
failed:
Expand Down
3 changes: 1 addition & 2 deletions config.local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ jobs:
- "/home/motalleb/Downloads:/var/local/test"
env:
SHELL: /bin/bash

schedulers:
events:
- on-init: true
- interval: 10m10s
14 changes: 7 additions & 7 deletions config/compiler/scheduler.go → config/compiler/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ import (
"github.com/FMotalleb/crontab-go/core/schedule"
)

func CompileScheduler(sh *config.JobScheduler, cr *cron.Cron, logger *logrus.Entry) abstraction.Scheduler {
func CompileEvent(sh *config.JobEvent, cr *cron.Cron, logger *logrus.Entry) abstraction.Event {
switch {
case sh.Cron != "":
scheduler := schedule.NewCron(
events := schedule.NewCron(
sh.Cron,
cr,
logger,
)
return &scheduler
return &events
case sh.Interval != 0:
scheduler := schedule.NewInterval(
events := schedule.NewInterval(
sh.Interval,
logger,
)
return &scheduler
return &events

case sh.OnInit:
scheduler := schedule.Init{}
return &scheduler
events := schedule.Init{}
return &events
}

return nil
Expand Down
88 changes: 88 additions & 0 deletions config/compiler/event_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cfgcompiler_test

import (
"testing"

"github.com/alecthomas/assert/v2"
"github.com/robfig/cron/v3"
"github.com/sirupsen/logrus"

"github.com/FMotalleb/crontab-go/config"
cfgcompiler "github.com/FMotalleb/crontab-go/config/compiler"
"github.com/FMotalleb/crontab-go/core/schedule"
mocklogger "github.com/FMotalleb/crontab-go/logger/mock_logger"
)

// TestCompileEvent_IntervalZero tests that CompileEvents returns nil when Interval is zero
func TestCompileEvent_IntervalZero(t *testing.T) {
sh := &config.JobEvent{Interval: 0}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

event := cfgcompiler.CompileEvent(sh, cr, log)
assert.Equal(t, event, nil)
}

func TestCompileEvent_IntervalNonZero(t *testing.T) {
sh := &config.JobEvent{Interval: 15}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

sch := cfgcompiler.CompileEvent(sh, cr, log)
_, ok := sch.(*schedule.Interval)
assert.Equal(t, ok, true)
}

// TestCompileEvent_IntervalZeroWithCronSet tests CompileEvents with Interval zero but Cron expression set
func TestCompileEvent_IntervalZeroWithCronSet(t *testing.T) {
sh := &config.JobEvent{Cron: "0 * * * *", Interval: 0}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

event := cfgcompiler.CompileEvent(sh, cr, log)
if _, ok := event.(*schedule.Cron); !ok {
t.Errorf("Expected Cron events, got %T", event)
}
}

// TestCompileEvent_IntervalZeroWithOnInitSet tests CompileEvents with Interval zero and OnInit set
func TestCompileEvent_IntervalZeroWithOnInitSet(t *testing.T) {
sh := &config.JobEvent{OnInit: true, Interval: 0}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

event := cfgcompiler.CompileEvent(sh, cr, log)
if _, ok := event.(*schedule.Init); !ok {
t.Errorf("Expected Init events, got %T", event)
}
}

// TestCompileEvent_IntervalZeroWithAllFieldsEmpty tests CompileEvents with Interval zero and all other fields empty
func TestCompileEvent_IntervalZeroWithAllFieldsEmpty(t *testing.T) {
sh := &config.JobEvent{Interval: 0}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

event := cfgcompiler.CompileEvent(sh, cr, log)
if event != nil {
t.Errorf("Expected nil, got %v", event)
}
}

// TestCompileEvent_IntervalZeroWithCronAndOnInitSet tests CompileEvent with Interval zero, Cron expression, and OnInit set
func TestCompileEvent_IntervalZeroWithCronAndOnInitSet(t *testing.T) {
sh := &config.JobEvent{Cron: "0 * * * *", OnInit: true, Interval: 0}
cr := cron.New()
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)

event := cfgcompiler.CompileEvent(sh, cr, log)
if _, ok := event.(*schedule.Cron); !ok {
t.Errorf("Expected Cron event, got %T", event)
}
}
5 changes: 4 additions & 1 deletion config/compiler/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ func CompileTask(t *config.Task, logger *logrus.Entry) abstraction.Executable {
case t.Post != "":
exe = task.NewPost(t, logger)
default:
logger.Fatalln("cannot handle given task config", t)
logger.Panic("cannot handle given task config", t)
}
if exe == nil {
logger.Panic("did not received any executable action from given task", t)
}

onDone := []abstraction.Executable{}
Expand Down
74 changes: 74 additions & 0 deletions config/compiler/task_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package cfgcompiler_test

import (
"testing"

"github.com/alecthomas/assert/v2"
"github.com/sirupsen/logrus"

"github.com/FMotalleb/crontab-go/config"
cfgcompiler "github.com/FMotalleb/crontab-go/config/compiler"
mocklogger "github.com/FMotalleb/crontab-go/logger/mock_logger"
)

func TestCompileTask_NonExistingTask(t *testing.T) {
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)
taskConfig := &config.Task{}
assert.Panics(
t,
func() {
cfgcompiler.CompileTask(taskConfig, log)
},
)
}

func TestCompileTask_GetTask(t *testing.T) {
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)
taskConfig := &config.Task{
Get: "test",
}
exe := cfgcompiler.CompileTask(taskConfig, log)
assert.NotEqual(t, exe, nil)
}

func TestCompileTask_CommandTask(t *testing.T) {
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)
taskConfig := &config.Task{
Command: "test",
}
exe := cfgcompiler.CompileTask(taskConfig, log)
assert.NotEqual(t, exe, nil)
}

func TestCompileTask_PostTask(t *testing.T) {
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)
taskConfig := &config.Task{
Post: "test",
}
exe := cfgcompiler.CompileTask(taskConfig, log)
assert.NotEqual(t, exe, nil)
}

func TestCompileTask_WithHooks(t *testing.T) {
logger, _ := mocklogger.HijackOutput(logrus.New())
log := logrus.NewEntry(logger)
taskConfig := &config.Task{
Command: "test",
OnDone: []config.Task{
{
Command: "test",
},
},
OnFail: []config.Task{
{
Command: "test",
},
},
}
exe := cfgcompiler.CompileTask(taskConfig, log)
assert.NotEqual(t, exe, nil)
}
Loading

0 comments on commit fc2ac68

Please sign in to comment.