resourcetree

package
v0.0.0-...-87426b5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2020 License: Apache-2.0 Imports: 7 Imported by: 0

README

Resource Tree

resourcetree package contains types and interfaces that define a resource tree(n-ary tree based representation of an API resource). Each resource tree is composed of nodes which have data encapsulated inside nodeData and operations that can be performed on each node in the interface NodeInterface. Type of a node is logically defined by reflect.Kind. Each node type is expected to satisfy the NodeInterface interface.

Resource Forest

ResourceForest groups all resource trees that are part of an API version into a single construct and defines operations that span across them. As an example for Knative Serving, we will have individual resource trees for Configuration, Revision, Route and Service, and they are encapsulated inside a resource forest under version v1alpha1. Example of an operation that spans resource trees would be to get coverage details for outlined types connected using ConnectedNodes.

ConnectedNodes represent connections between nodes that are of same type(reflect.Type) and belong to same package but span across different trees or branches of same tree. An example of ConnectedNodes would be v1alpha1.Route.Spec.Traffic and v1alpha1.Route.Status.Traffic, both these Traffic fields are of type v1alpha1.TrafficTarget, but are present in different paths inside the resource tree. ConnectedNodes connects these two nodes, and an outlining of this type would present the coverage across the two branches and gives a unified view of what fields are covered.

Type Analysis

A Resource tree is built using reflect.Type Each node type is expected to implement NodeInterface method buildChildNodes(t reflect.Type). Inside this method each node creates child nodes based on its type, for e.g. StructKindNode creates one child for each field defined in the struct. Type analysis are defined inside typeanalyzer_tests

Value Analysis

A Resource tree is updated using reflect.Value Each node type is expected to implement NodeInterface method updateCoverage(v reflect.Value). Inisde this method each node updates its nodeData.covered field based on whether the reflect.Value parameter being passed is set or not.

Rules

To define traversal pattern on a resourcetree coveragecalculator package supports defining rules that are applied during apicoverage walk-through. Currently the tool supports two types of Rule objects:

  1. NodeRules: Enforces node level semantics. e.g.: Avoid traversing any type that belong to a particular package. To enforce this rule, the repo would define an object that implements the NodeRule interface's Apply(nodeInterface resourcetree.NodeInterface) bool method and pass that onto the resourcetree traversal routine.

  2. FieldRules: Enforces field level semantics. e.g. Avoid calculating coverage for any field that starts with prefix deprecated. To enforce this rule, the repo would define an object that implements FieldRule interface's Apply(fieldName string) bool method and pass that onto the resourcetree traversal routine.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ArrayKindNode

type ArrayKindNode struct {
	NodeData
	// contains filtered or unexported fields
}

ArrayKindNode represents resource tree node of types reflect.Kind.Array and reflect.Kind.Slice

func (*ArrayKindNode) GetData

func (a *ArrayKindNode) GetData() NodeData

GetData returns node data

type BasicTypeKindNode

type BasicTypeKindNode struct {
	NodeData
	// contains filtered or unexported fields
}

BasicTypeKindNode represents resource tree node of basic types like int, float, etc.

func (*BasicTypeKindNode) GetData

func (b *BasicTypeKindNode) GetData() NodeData

GetData returns node data

type FieldRules

type FieldRules struct {
	Rules []func(fieldName string) bool
}

FieldRules encapsulates all the field level rules defined by a repo.

func (*FieldRules) Apply

func (f *FieldRules) Apply(fieldName string) bool

Apply runs all the rules defined by a repo against a field.

type NodeData

type NodeData struct {
	// Represents the Name of the field e.g. field name inside the struct.
	Field string
	// Reference back to the resource tree. Required for cross-tree traversal(connected nodes traversal)
	Tree *ResourceTree
	// Required as type information is not available during tree traversal.
	FieldType reflect.Type
	// Path in the resource tree reaching this node.
	NodePath string
	// Link back to parent.
	Parent NodeInterface
	// Child nodes are keyed using field names(nodeData.field).
	Children map[string]NodeInterface
	// Storing this as an additional field because type-analysis determines the value,
	// which gets used later in value-evaluation
	LeafNode bool
	Covered  bool
}

NodeData is the data stored in each node of the resource tree.

type NodeInterface

type NodeInterface interface {
	GetData() NodeData
	// contains filtered or unexported methods
}

NodeInterface defines methods that can be performed on each node in the resource tree.

type NodeRules

type NodeRules struct {
	Rules []func(nodeInterface NodeInterface) bool
}

NodeRules encapsulates all the node level rules defined by a repo.

func (*NodeRules) Apply

func (n *NodeRules) Apply(node NodeInterface) bool

Apply runs all the rules defined by a repo against a node.

type OtherKindNode

type OtherKindNode struct {
	NodeData
}

OtherKindNode represents nodes in the resource tree of types like maps, interfaces, etc

func (*OtherKindNode) GetData

func (o *OtherKindNode) GetData() NodeData

GetData returns node data

type PtrKindNode

type PtrKindNode struct {
	NodeData
	// contains filtered or unexported fields
}

PtrKindNode represents nodes in the resource tree of type reflect.Kind.Ptr, reflect.Kind.UnsafePointer, etc.

func (*PtrKindNode) GetData

func (p *PtrKindNode) GetData() NodeData

GetData returns node data

type ResourceForest

type ResourceForest struct {
	Version string
	// Key is ResourceTree.ResourceName
	TopLevelTrees map[string]ResourceTree
	// Head of the linked list keyed by nodeData.fieldType.pkg + nodeData.fieldType.Name()
	ConnectedNodes map[string]*list.List
}

ResourceForest represents the top-level forest that contains individual resource trees for top-level resource types and all connected nodes across resource trees.

func (*ResourceForest) AddResourceTree

func (r *ResourceForest) AddResourceTree(resourceName string, resourceType reflect.Type)

AddResourceTree adds a resource tree to the resource forest.

type ResourceTree

type ResourceTree struct {
	ResourceName string
	Root         NodeInterface
	Forest       *ResourceForest
}

ResourceTree encapsulates a tree corresponding to a resource type.

func (*ResourceTree) BuildCoverageData

func (r *ResourceTree) BuildCoverageData(nodeRules NodeRules, fieldRules FieldRules,
	ignoredFields coveragecalculator.IgnoredFields) []coveragecalculator.TypeCoverage

BuildCoverageData calculates the coverage information for a resource tree by applying provided Node and Field rules.

func (*ResourceTree) BuildResourceTree

func (r *ResourceTree) BuildResourceTree(t reflect.Type)

BuildResourceTree builds a resource tree by calling into analyzeType method starting from root.

func (*ResourceTree) UpdateCoverage

func (r *ResourceTree) UpdateCoverage(v reflect.Value)

UpdateCoverage updates coverage data in the resource tree based on the provided reflect.Value

type StructKindNode

type StructKindNode struct {
	NodeData
}

StructKindNode represents nodes in the resource tree of type reflect.Kind.Struct

func (*StructKindNode) GetData

func (s *StructKindNode) GetData() NodeData

GetData returns node data

type TimeTypeNode

type TimeTypeNode struct {
	NodeData
}

TimeTypeNode is a node type that encapsulates fields that are internally time based. E.g metav1.ObjectMeta.CreationTimestamp or metav1.ObjectMeta.DeletionTimestamp. These are internally of type metav1.Time which use standard time type, but their values are specified as timestamp strings with parsing logic to create time objects. For use-case we only care if the value is set, so we create TimeTypeNodes and mark them as leafnodes.

func (*TimeTypeNode) GetData

func (ti *TimeTypeNode) GetData() NodeData

GetData returns node data

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL