Skip to content

Commit

Permalink
docs: improve doc comments of the module interface
Browse files Browse the repository at this point in the history
Signed-off-by: Jens Drenhaus <jens.drenhaus@blindspot.software>
  • Loading branch information
jensdrenhaus committed Oct 17, 2024
1 parent 2e7d227 commit 39a7e7b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
2 changes: 1 addition & 1 deletion pkg/module/dummy/dummy_file_transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func init() {
module.Register(module.Info{
module.Register(module.Record{
ID: "dummy-ft",
New: func() module.Module { return &FT{} },
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/module/dummy/dummy_repeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func init() {
module.Register(module.Info{
module.Register(module.Record{
ID: "dummy-repeat",
New: func() module.Module { return &Repeat{} },
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/module/dummy/dummy_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func init() {
module.Register(module.Info{
module.Register(module.Record{
ID: "dummy-status",
New: func() module.Module { return &Status{} },
})
Expand Down
43 changes: 28 additions & 15 deletions pkg/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,31 @@ import (

//nolint:gochecknoglobals
var (
modules = make(map[string]Info)
modules = make(map[string]Record)
mutex sync.RWMutex
)

// Module is a building block of a command running on a device-under-test (DUT).
// Implementations of this interface are the actual steps that are executed on a DUT.
type Module interface {
// Help returns a formatted string with the capabilities of the module.
// It provides any user information required to interact with the module.
// Help provides usage information.
// The returned string should contain a description of the module the supported
// command line arguments and any other information required to interact with the module.
// The returned string should be formatted in a way that it can be displayed to the user.
//
// Implementations should consider the module's concrete configuration and potentially
// return individual help messages based on the configuration. It is not the purpose
// of this method to provide a generic help message for all possible configurations,
// but rather usage information for the current configuration.
Help() string
// Init is called once when the dutagent services is started.
// It's a good place to establish connections or allocate resources and check whether
// the module is configured functional
// the module is configured functional. It is also called when a command containing this
// module is called as a dry-run to check the configuration.
Init() error
// Deinit is called when the module is unloaded by dutagent or an internal error occurs.
// It is used to clean up any resources that were allocated during the Init phase and
// shall guarantee a graceful shutdown of the service
// shall guarantee a graceful shutdown of the service.
Deinit() error
// Run is the entry point and executes the module with the given arguments.
Run(ctx context.Context, s Session, args ...string) error
Expand All @@ -49,37 +57,42 @@ type Session interface {
SendFile(name string, r io.Reader) error
}

// Info holds the information required to register a module.
type Info struct {
// Record holds the information required to register a module.
type Record struct {
// ID is the unique identifier of the module.
// It is used to reference the module in the dutagent configuration.
ID string
// New is the factory function that creates a new instance of the module.
// Most of the time, this function will return a pointer to a newly allocated struct
// that implements the Module interface. It is not supposed to run initialization code
// with side effects. The actual initialization should be done in the Init method of the Module.
// Instead the factory function may serve as a constructor for the module and can be used to
// allocate internal resources, like maps and slices or set up the initial state of the module.
New func() Module
}

// Register registers a module for use in dutagent.
func Register(mod Info) {
if mod.ID == "" {
func Register(r Record) {
if r.ID == "" {
panic("module ID missing")
}

if mod.ID == "help" || mod.ID == "info" {
panic(fmt.Sprintf("module ID '%s' is reserved", mod.ID))
if r.ID == "help" || r.ID == "info" {
panic(fmt.Sprintf("module ID '%s' is reserved", r.ID))
}

if mod.New == nil {
if r.New == nil {
panic("missing factory function 'New func() Module'")
}

mutex.Lock()
defer mutex.Unlock()

if _, ok := modules[mod.ID]; ok {
panic(fmt.Sprintf("module already registered: %s", mod.ID))
if _, ok := modules[r.ID]; ok {
panic(fmt.Sprintf("module already registered: %s", r.ID))
}

modules[mod.ID] = mod
modules[r.ID] = r
}

// New creates a new instance of a former registered module by its ID.
Expand Down

0 comments on commit 39a7e7b

Please sign in to comment.