buganizer

package
v0.0.0-...-d3da680 Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2024 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package buganizer contains methods to manage issues in Issue Tracker linked to failure association rules.

Index

Constants

View Source
const (
	ModeDisable  = "disable"
	ModeProvided = "provided"
)

The modes for the buganizer integration client. Each mode defines how LUCI Analysis will behave with Buganizer. `ModeDisable` is the default mode, and ignores Buganizer bugs. `ModeProvided` uses the provided Buganizer integration client.

View Source
const ComponentWithNoAccess = 999999

ComponentWithNoAccess is a componentID for which all access checks to the fake client will return false.

Variables

View Source
var BuganizerClientModeKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:buganizerMode"

BuganizerClientModeKey the key to get the value for Buganizer integration mode from the Context.

View Source
var BuganizerEndpointBaseKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:buganizerEndpointBase"

BuganizerEndpointBaseKey the key to get the value for Buganizer's endpoint base subdomain from the Context.

View Source
var BuganizerEndpointOAuthScopeKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:buganizerEndpointOAuthScopeKey"

BuganizerEndpointOAuthScopeKey the key to get the value for Buganier OAuth scope from the context.

View Source
var BuganizerSelfEmailKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:luciAnalysisBuganizerEmailKey"

BuganizerSelfEmailKey the context key to get email that LUCI Analysis uses to file bugs in Buganizer.

View Source
var BuganizerTestComponentIdKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:buganizerTestComponentIdKey"

BuganizerTestComponentIdKey the context key to get Buganizer test component id.

View Source
var BuganizerTestModeKey = "go.chromium.org/luci/analysis/internal/bugs/buganizer:buganizerTestModeKey"

BuganizerTestModeKey the context key to get whether Buganizer is in test mode.

View Source
var ClosedStatuses = map[issuetracker.Issue_Status]struct{}{
	issuetracker.Issue_FIXED:             {},
	issuetracker.Issue_VERIFIED:          {},
	issuetracker.Issue_NOT_REPRODUCIBLE:  {},
	issuetracker.Issue_INFEASIBLE:        {},
	issuetracker.Issue_INTENDED_BEHAVIOR: {},
}

The status which are consider to be closed.

View Source
var ModuleName = module.RegisterName("go.chromium.org/luci/analysis/internal/bugs/buganizer")

ModuleName can be used to refer to this module when declaring dependencies.

Functions

func ChromeOSTestConfig

func ChromeOSTestConfig() *configpb.BuganizerProject

func CreateSampleIssue

func CreateSampleIssue(ctx context.Context) (int64, error)

func NewFakeIssue

func NewFakeIssue(issueId int64) *issuetracker.Issue

func NewModule

func NewModule(opts *ModuleOptions) module.Module

NewModule returns a server module that sets a context value for Buganizer integration mode. That value can be used to determine how the server will interact with Buganizer.

func NewModuleFromFlags

func NewModuleFromFlags() module.Module

NewModuleFromFlags is a variant of NewModule that initializes options through command line flags.

Calling this function registers flags in flag.CommandLine. They are usually parsed in server.Main(...).

func PrepareHotlistInsertions

func PrepareHotlistInsertions(hotlistIDs map[int64]struct{}, issueID int64) []*issuetracker.CreateHotlistEntryRequest

PrepareHotlistInsertions returns the CreateHotlistEntry requests necessary to insert the issue in the hotlists specified by its bug managment policies.

Types

type BugManager

type BugManager struct {
	// contains filtered or unexported fields
}

func NewBugManager

func NewBugManager(client Client,
	uiBaseURL, project, selfEmail string,
	projectCfg *configpb.ProjectConfig) (*BugManager, error)

NewBugManager creates a new Buganizer bug manager than can be used to manipulate bugs in Buganizer.

func (*BugManager) Create

func (bm *BugManager) Create(ctx context.Context, createRequest bugs.BugCreateRequest) bugs.BugCreateResponse

Create creates an issue in Buganizer and returns the issue ID.

func (*BugManager) GetMergedInto

func (bm *BugManager) GetMergedInto(ctx context.Context, bug bugs.BugID) (*bugs.BugID, error)

GetMergedInto returns the canonical bug id that this issue is merged into.

func (*BugManager) Update

func (bm *BugManager) Update(ctx context.Context, requests []bugs.BugUpdateRequest) ([]bugs.BugUpdateResponse, error)

Update updates the issues in Buganizer.

func (*BugManager) UpdateDuplicateSource

func (bm *BugManager) UpdateDuplicateSource(ctx context.Context, request bugs.UpdateDuplicateSourceRequest) error

UpdateDuplicateSource updates the source bug of a duplicate bug relationship. It normally posts a message advising the user LUCI Analysis has merged the rule for the source bug to the destination (merged-into) bug, and provides a new link to the failure association rule. If a cycle was detected, it instead posts a message that the duplicate bug could not be handled and marks the bug no longer a duplicate to break the cycle.

type Client

type Client interface {
	// Closes the underlying client.
	Close()
	// BatchGetIssues returns a list of issues matching the BatchGetIssuesRequest.
	BatchGetIssues(ctx context.Context, in *issuetracker.BatchGetIssuesRequest) (*issuetracker.BatchGetIssuesResponse, error)
	// GetComponent gets a component, including its parent hierarchy info.
	GetComponent(ctx context.Context, in *issuetracker.GetComponentRequest) (*issuetracker.Component, error)
	// GetIssue returns data about a single issue.
	GetIssue(ctx context.Context, in *issuetracker.GetIssueRequest) (*issuetracker.Issue, error)
	// CreateIssue creates an issue using the data provided.
	CreateIssue(ctx context.Context, in *issuetracker.CreateIssueRequest) (*issuetracker.Issue, error)
	// ModifyIssue modifies an issue using the data provided.
	ModifyIssue(ctx context.Context, in *issuetracker.ModifyIssueRequest) (*issuetracker.Issue, error)
	// ListIssueUpdates lists the updates which occured in an issue, it returns a delegate to an IssueUpdateIterator.
	// The iterator can be used to fetch IssueUpdates one by one.
	ListIssueUpdates(ctx context.Context, in *issuetracker.ListIssueUpdatesRequest) IssueUpdateIterator
	// CreateIssueComment creates an issue comment using the data provided.
	CreateIssueComment(ctx context.Context, in *issuetracker.CreateIssueCommentRequest) (*issuetracker.IssueComment, error)
	// UpdateIssueComment updates an issue comment and returns the updated comment.
	UpdateIssueComment(ctx context.Context, in *issuetracker.UpdateIssueCommentRequest) (*issuetracker.IssueComment, error)
	// ListIssueComments lists issue comments, it returns a delegate to an IssueCommentIterator.
	// The iterator can be used to fetch IssueComment one by one.
	ListIssueComments(ctx context.Context, in *issuetracker.ListIssueCommentsRequest) IssueCommentIterator
	// GetAutomationAccess checks that automation has permission on a resource.
	// Does not require any permission on the resource
	GetAutomationAccess(ctx context.Context, in *issuetracker.GetAutomationAccessRequest) (*issuetracker.GetAutomationAccessResponse, error)
	// CreateHotlistEntry adds an issue to a hotlist.
	CreateHotlistEntry(ctx context.Context, in *issuetracker.CreateHotlistEntryRequest) (*issuetracker.HotlistEntry, error)
}

Client represents the interface needed by the bug manager to manipulate issues in Google Issue Tracker.

type ComponentAccessChecker

type ComponentAccessChecker struct {
	// contains filtered or unexported fields
}

func NewComponentAccessChecker

func NewComponentAccessChecker(client Client, emailAddress string) *ComponentAccessChecker

NewComponentAccessChecker initialises a new component access checker. client is the issue tracker to use, and emailAddress is the email address of the user to check access of (this should be the service's own email).

func (*ComponentAccessChecker) CheckAccess

func (c *ComponentAccessChecker) CheckAccess(ctx context.Context, componentID int64) (ComponentPermissions, error)

CheckAccess checks the permissions required to create an issue in the specified component.

type ComponentPermissions

type ComponentPermissions struct {
	// Appender is permission to create issues in this component.
	Appender bool
	// IssueDefaultsAppender is permission to add comments to issues in
	// this component.
	IssueDefaultsAppender bool
}

ComponentPermissions contains the results of checking the permissions of a Buganizer component.

type FakeClient

type FakeClient struct {
	FakeStore *FakeIssueStore
	// Defines a custom error to return when attempting to create
	// an issue comment. Use this to test failed updates.
	CreateCommentError error
	// Defines the component access level. Defaults to `AccessLimit_INTERNAL`.
	ComponentAccessLevel issuetracker.AccessLimit_AccessLevel
}

FakeClient is an implementation of ClientWrapperInterface that fakes the actions performed using an in-memory store.

func NewFakeClient

func NewFakeClient() *FakeClient

func (*FakeClient) BatchGetIssues

func (fic *FakeClient) BatchGetIssues(ctx context.Context, in *issuetracker.BatchGetIssuesRequest) (*issuetracker.BatchGetIssuesResponse, error)

func (*FakeClient) Close

func (fic *FakeClient) Close()

Required by interface but doesn't perform any closer in the fake state.

func (*FakeClient) CreateHotlistEntry

func (fic *FakeClient) CreateHotlistEntry(ctx context.Context, in *issuetracker.CreateHotlistEntryRequest) (*issuetracker.HotlistEntry, error)

func (*FakeClient) CreateIssue

func (fic *FakeClient) CreateIssue(ctx context.Context, in *issuetracker.CreateIssueRequest) (*issuetracker.Issue, error)

CreateIssue creates an issue in the in-memory store.

func (*FakeClient) CreateIssueComment

func (fic *FakeClient) CreateIssueComment(ctx context.Context, in *issuetracker.CreateIssueCommentRequest) (*issuetracker.IssueComment, error)

func (*FakeClient) GetAutomationAccess

func (fic *FakeClient) GetAutomationAccess(ctx context.Context, in *issuetracker.GetAutomationAccessRequest) (*issuetracker.GetAutomationAccessResponse, error)

GetAutomationAccess checks access to a ComponentID. Access is always true except for component ID ComponentWithNoAccess which is false.

func (*FakeClient) GetComponent

func (fic *FakeClient) GetComponent(ctx context.Context, in *issuetracker.GetComponentRequest) (*issuetracker.Component, error)

func (*FakeClient) GetIssue

func (fic *FakeClient) GetIssue(ctx context.Context, in *issuetracker.GetIssueRequest) (*issuetracker.Issue, error)

func (*FakeClient) ListIssueComments

func (fic *FakeClient) ListIssueComments(ctx context.Context, in *issuetracker.ListIssueCommentsRequest) IssueCommentIterator

func (*FakeClient) ListIssueUpdates

func (fic *FakeClient) ListIssueUpdates(ctx context.Context, in *issuetracker.ListIssueUpdatesRequest) IssueUpdateIterator

func (*FakeClient) ModifyIssue

func (fic *FakeClient) ModifyIssue(ctx context.Context, in *issuetracker.ModifyIssueRequest) (*issuetracker.Issue, error)

ModifyIssue modifies and issue in the in-memory store. This method handles a specific set of updates, please check the implementation and add any required field to the set of known fields.

func (*FakeClient) UpdateIssueComment

func (fic *FakeClient) UpdateIssueComment(ctx context.Context, in *issuetracker.UpdateIssueCommentRequest) (*issuetracker.IssueComment, error)

type FakeIssueStore

type FakeIssueStore struct {
	// A map of issue id to issue data. Used as an in-memory store.
	Issues map[int64]*IssueData
	// contains filtered or unexported fields
}

fakeIssueStore is an in-memory store for issues. The store doesn't generate the corresponding IssueUpdate for an issue update.

func NewFakeIssueStore

func NewFakeIssueStore() *FakeIssueStore

Creates a new in-memory fake issue store.

func (*FakeIssueStore) BatchGetIssues

func (fis *FakeIssueStore) BatchGetIssues(issueIds []int64) ([]*issuetracker.Issue, error)

func (*FakeIssueStore) CreateHotlistEntry

func (fis *FakeIssueStore) CreateHotlistEntry(issueID int64, hotlistID int64) error

func (*FakeIssueStore) GetIssue

func (fis *FakeIssueStore) GetIssue(id int64) (*IssueData, error)

func (*FakeIssueStore) ListIssueUpdates

func (fis *FakeIssueStore) ListIssueUpdates(id int64) ([]*issuetracker.IssueUpdate, error)

func (*FakeIssueStore) StoreIssue

func (fis *FakeIssueStore) StoreIssue(ctx context.Context, issue *issuetracker.Issue) *issuetracker.Issue

StoreIssue creates an issue in the in-memory store, assigning it an ID (if unset) and creation timestamps. The issue that was stored is returned.

type IssueCommentIterator

type IssueCommentIterator interface {
	// Next returns the next comment in the list of comments.
	// If the error is iterator.Done, this means that the iterator is exhausted.
	// Once iterator.Done is returned, it will always be returned thereafter.
	Next() (*issuetracker.IssueComment, error)
}

An interface for the IssueCommentIterator.

type IssueData

type IssueData struct {
	// The issue itself.
	Issue *issuetracker.Issue
	// All comments for the issue.
	Comments []*issuetracker.IssueComment
	// The updates on the issue.
	IssueUpdates []*issuetracker.IssueUpdate
	// The list of issue relationships this issue has.
	// Use this field to set source and destination relationsships
	// of duplicate issues.
	IssueRelationships []*issuetracker.IssueRelationship
	// Defines a custom error to return when attempting to update
	// the issue. Use this to test failed updates.
	UpdateError error
	// Determines whether the issue should return grpc permission
	// error when accessed or updated.
	ShouldReturnAccessPermissionError bool
}

issueData represents all data that the store keeps for an issue.

type IssueUpdateIterator

type IssueUpdateIterator interface {
	// Next returns the next update in the list of updates.
	// If the error is iterator.Done, this means that the iterator is exhausted.
	// Once iterator.Done is returned, it will always be returned thereafter.
	Next() (*issuetracker.IssueUpdate, error)
}

An interface for an IssueUpdateIterator.

type MakeUpdateOptions

type MakeUpdateOptions struct {
	// The identifier of the rule making the update.
	RuleID string
	// The bug management state.
	BugManagementState *bugspb.BugManagementState
	// The Issue to update.
	Issue *issuetracker.Issue
	// Indicates whether the rule is managing bug priority or not.
	// Use the value on the rule; do not yet set it to false if
	// HasManuallySetPriority is true.
	IsManagingBugPriority bool
	// Whether the user has manually taken control of the bug priority.
	HasManuallySetPriority bool
}

type MakeUpdateResult

type MakeUpdateResult struct {
	// contains filtered or unexported fields
}

MakeUpdateResult is the result of MakePriorityOrVerifiedUpdate.

type ModuleOptions

type ModuleOptions struct {
	// Option for the buganizer management, defaults to `disable`
	// Acceptable values are:
	// `disable` - Indicates that Buganizer integration should not be used.
	// `provided` - Indicates that Buganizer integration should use provided client.
	// `fake` - Indicates that Buganizer integration should use the fake Buganizer implementation.
	BuganizerClientMode string

	// Option that indicates the base subdomain for the Buganizer endpoint.
	// For example: placeholder-issuetracker-c2p, that value will
	// be used by the clients to initiate connections with Buganizer.
	BuganizerEndpointBase string

	// Option for which OAuth scope to use for PerRPC credentials
	// for the Buganizer client to use for authenticating requests.
	// Example: "https://www.googleapis.com/auth/placeholder".
	BuganizerEndpointOAuthScope string

	// The component ID used for creating test issues in Buganizer.
	BuganizerTestComponentId int64

	// The email used by LUCI Analysis to file bugs.
	BuganizerSelfEmail string

	// Whether Buganizer is being used in a test environment.
	BuganizerTestMode bool
}

ModuleOptions contain configuartion for the Buganizer module.

func (*ModuleOptions) Register

func (o *ModuleOptions) Register(f *flag.FlagSet)

Register registers the command line flags.

type RPCClient

type RPCClient struct {
	Client *issuetrackerclient.Client
}

RPCClient is an implementation of the client wrapper that uses the Client provided by issuetrackerclient package. This client acts as a delegate and a proxy to the actual implementation.

func CreateBuganizerClient

func CreateBuganizerClient(ctx context.Context) (*RPCClient, error)

CreateBuganizerClient returns a Buganizer client, configured based on server settings passed to main.go. If Buganizer is not configured, returns a nil client.

func NewRPCClient

func NewRPCClient(ctx context.Context) (*RPCClient, error)

NewRPCClient returns a new ClientWrapper.

func (*RPCClient) BatchGetIssues

func (w *RPCClient) BatchGetIssues(ctx context.Context, in *issuetracker.BatchGetIssuesRequest) (*issuetracker.BatchGetIssuesResponse, error)

BatchGetIssues delegates a call to Client.BatchGetIssues and returns the list of issues returned or the error that occured.

func (*RPCClient) Close

func (w *RPCClient) Close()

func (*RPCClient) CreateHotlistEntry

func (w *RPCClient) CreateHotlistEntry(ctx context.Context, in *issuetracker.CreateHotlistEntryRequest) (*issuetracker.HotlistEntry, error)

CreateHotlistEntry delegates a call to Client.CreateHotlistEntry and returns the created hotlist entry or the error that occured.

func (*RPCClient) CreateIssue

func (w *RPCClient) CreateIssue(ctx context.Context, in *issuetracker.CreateIssueRequest) (*issuetracker.Issue, error)

CreateIssue delegates a call to Client.CreateIssue and returns the issue that was created or the error that occured.

func (*RPCClient) CreateIssueComment

func (w *RPCClient) CreateIssueComment(ctx context.Context, in *issuetracker.CreateIssueCommentRequest) (*issuetracker.IssueComment, error)

CreateIssueComment delegates a call to Client.CreateIssueComment and returns the comment that was created or the error that occured.

func (*RPCClient) GetAutomationAccess

func (w *RPCClient) GetAutomationAccess(ctx context.Context, in *issuetracker.GetAutomationAccessRequest) (*issuetracker.GetAutomationAccessResponse, error)

GetAutomationAccess delegates a call to Client.GetIssue and returns the access returned or the error that occured.

func (*RPCClient) GetComponent

func (w *RPCClient) GetComponent(ctx context.Context, in *issuetracker.GetComponentRequest) (*issuetracker.Component, error)

GetComponent delegates a call to Client.GetComponent and returns the component returned or the error that occured.

func (*RPCClient) GetIssue

func (w *RPCClient) GetIssue(ctx context.Context, in *issuetracker.GetIssueRequest) (*issuetracker.Issue, error)

GetIssue delegates a call to Client.GetIssue and returns the issue returned or the error that occured.

func (*RPCClient) ListIssueComments

func (w *RPCClient) ListIssueComments(ctx context.Context, in *issuetracker.ListIssueCommentsRequest) IssueCommentIterator

ListIssueComments delegates a call to Client.ListIssueComments and returns the issue comment iterator delegate.

func (*RPCClient) ListIssueUpdates

func (w *RPCClient) ListIssueUpdates(ctx context.Context, in *issuetracker.ListIssueUpdatesRequest) IssueUpdateIterator

ListIssueUpdates delegates a call to Client.ListIssueUpdates and returns the issue updates iterator delegate.

func (*RPCClient) ModifyIssue

func (w *RPCClient) ModifyIssue(ctx context.Context, in *issuetracker.ModifyIssueRequest) (*issuetracker.Issue, error)

ModifyIssue delegates a call to Client.ModifyIssue and returns the modified issue or the error that occured.

func (*RPCClient) UpdateIssueComment

func (w *RPCClient) UpdateIssueComment(ctx context.Context, in *issuetracker.UpdateIssueCommentRequest) (*issuetracker.IssueComment, error)

UpdateIssueComment delegates a call to Client.UpdateIssueComment and returns the updated comment or the error that occured.

type RequestGenerator

type RequestGenerator struct {
	// contains filtered or unexported fields
}

RequestGenerator generates new bugs or prepares existing ones for updates.

func NewRequestGenerator

func NewRequestGenerator(
	client Client,
	project, uiBaseURL, selfEmail string,
	projectCfg *configpb.ProjectConfig) (*RequestGenerator, error)

NewRequestGenerator initializes a new buganizer request generator.

func (*RequestGenerator) ExpectedHotlistIDs

func (rg *RequestGenerator) ExpectedHotlistIDs(activePolicyIDs map[bugs.PolicyID]struct{}) map[int64]struct{}

func (*RequestGenerator) MakePriorityOrVerifiedUpdate

func (rg *RequestGenerator) MakePriorityOrVerifiedUpdate(options MakeUpdateOptions) (MakeUpdateResult, error)

MakePriorityOrVerifiedUpdate prepares a priority and/or verified update for the bug with the given bug management state. **Must** ONLY be called if NeedsPriorityOrVerifiedUpdate(...) returns true.

func (*RequestGenerator) NeedsPriorityOrVerifiedUpdate

func (rg *RequestGenerator) NeedsPriorityOrVerifiedUpdate(bms *bugspb.BugManagementState,
	issue *issuetracker.Issue,
	isManagingBugPriority bool) bool

NeedsPriorityOrVerifiedUpdate returns whether the bug priority and/or verified status needs to be updated.

func (*RequestGenerator) PrepareNew

func (rg *RequestGenerator) PrepareNew(description *clustering.ClusterDescription, activePolicyIDs map[bugs.PolicyID]struct{},
	ruleID string, component *issuetracker.Component) (*issuetracker.CreateIssueRequest, error)

PrepareNew generates a CreateIssueRequest for a new issue.

func (*RequestGenerator) PrepareNoPermissionComment

func (rg *RequestGenerator) PrepareNoPermissionComment(issueID, componentID int64) *issuetracker.CreateIssueCommentRequest

PrepareNoPermissionComment prepares a request that adds links to LUCI Analysis to a Buganizer bug.

func (*RequestGenerator) PreparePolicyActivatedComment

func (rg *RequestGenerator) PreparePolicyActivatedComment(ruleID string, issueID int64, policyID bugs.PolicyID) (*issuetracker.CreateIssueCommentRequest, error)

PreparePolicyActivatedComment prepares a request that notifies a bug that a policy has activated for the first time. If the policy has not specified a comment to post, this method returns nil.

func (*RequestGenerator) PrepareRuleAssociatedComment

func (rg *RequestGenerator) PrepareRuleAssociatedComment(ruleID string, issueID int64) (*issuetracker.CreateIssueCommentRequest, error)

PrepareRuleAssociatedComment prepares a request that notifies the bug it is associated with failures in LUCI Analysis.

func (*RequestGenerator) SortPolicyIDsByPriorityDescending

func (rg *RequestGenerator) SortPolicyIDsByPriorityDescending(policyIDs map[bugs.PolicyID]struct{}) []bugs.PolicyID

SortPolicyIDsByPriorityDescending sorts policy IDs in descending priority order (i.e. P0 policies first, then P1, then P2, ...).

func (*RequestGenerator) UpdateDuplicateSource

func (rg *RequestGenerator) UpdateDuplicateSource(issueID int64, errorMessage, sourceRuleID, destinationRuleID string, isAssigned bool) *issuetracker.ModifyIssueRequest

UpdateDuplicateSource updates the source bug of a (source, destination) duplicate bug pair, after LUCI Analysis has attempted to merge their failure association rules.

Jump to

Keyboard shortcuts

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