aboutsummaryrefslogblamecommitdiffstats
path: root/misc/random_bugs/create_random_bugs.go
blob: 3d93135ece4bf3b78e28c2cdbd72234525f1669f (plain) (tree)
1
2
3
4
5
6
7
8
9
                   


                   


                 

                                  
                                            
                                                 
                                                   

 
                                                                
 















                                 










                                                                               
                                                                  
                                                                   

 
                                                                                      


                                                      








                                     
                                                                      

                       
 





                                                                        




                                        

                      

         

                                                  
                                             

                                        
                                        
                                       



                                          




                                  





                                                                  

                                                              

                                                                          

                 












                                                                                                          


                                                                                                        









                                                        
                                     
                                       




                                          



                                                 
                                                 
                                               



                                                  
                                      
                 

                               
         

                     

 

                                                                               

 
                                
 
                                                                
                                               
                                




                                      

                                  
                 
                              
         
 
 

                                        







                                                   

                                                                      

 

                                                                    

 

                                                                   

 

                                                                    



                        
                                                                     






                                                                    
                           









                                                        


                                                         
                                                                   
 
package random_bugs

import (
	"math/rand"
	"strings"
	"time"

	"github.com/icrowley/fake"

	"github.com/MichaelMure/git-bug/bug"
	"github.com/MichaelMure/git-bug/identity"
	"github.com/MichaelMure/git-bug/repository"
)

type opsGenerator func(bug.Interface, identity.Interface, int64)

type Options struct {
	BugNumber    int
	PersonNumber int
	MinOp        int
	MaxOp        int
}

func DefaultOptions() Options {
	return Options{
		BugNumber:    15,
		PersonNumber: 5,
		MinOp:        3,
		MaxOp:        20,
	}
}

func FillRepo(repo repository.ClockedRepo, bugNumber int) {
	FillRepoWithSeed(repo, bugNumber, time.Now().UnixNano())
}

func FillRepoWithSeed(repo repository.ClockedRepo, bugNumber int, seed int64) {
	options := DefaultOptions()
	options.BugNumber = bugNumber

	CommitRandomBugsWithSeed(repo, options, seed)
}

func CommitRandomBugs(repo repository.ClockedRepo, opts Options) {
	CommitRandomBugsWithSeed(repo, opts, time.Now().UnixNano())
}

func CommitRandomBugsWithSeed(repo repository.ClockedRepo, opts Options, seed int64) {
	generateRandomPersons(repo, opts.PersonNumber)

	bugs := generateRandomBugsWithSeed(opts, seed)

	for _, b := range bugs {
		err := b.Commit(repo)
		if err != nil {
			panic(err)
		}
	}
}

func generateRandomBugsWithSeed(opts Options, seed int64) []*bug.Bug {
	rand.Seed(seed)
	fake.Seed(seed)

	// At the moment git-bug has a risk of hash collision is simple
	// operation (like open/close) are made with the same timestamp.
	// As a temporary workaround, we use here an strictly increasing
	// timestamp
	timestamp := time.Now().Unix()

	opsGenerators := []opsGenerator{
		comment,
		comment,
		title,
		labels,
		open,
		close,
	}

	result := make([]*bug.Bug, opts.BugNumber)

	for i := 0; i < opts.BugNumber; i++ {
		addedLabels = []string{}

		b, _, err := bug.Create(
			randomPerson(),
			time.Now().Unix(),
			fake.Sentence(),
			paragraphs(),
		)

		if err != nil {
			panic(err)
		}

		nOps := opts.MinOp

		if opts.MaxOp > opts.MinOp {
			nOps += rand.Intn(opts.MaxOp - opts.MinOp)
		}

		for j := 0; j < nOps; j++ {
			index := rand.Intn(len(opsGenerators))
			opsGenerators[index](b, randomPerson(), timestamp)
			timestamp++
		}

		result[i] = b
	}

	return result
}

func GenerateRandomOperationPacks(packNumber int, opNumber int) []*bug.OperationPack {
	return GenerateRandomOperationPacksWithSeed(packNumber, opNumber, time.Now().UnixNano())
}

func GenerateRandomOperationPacksWithSeed(packNumber int, opNumber int, seed int64) []*bug.OperationPack {
	// Note: this is a bit crude, only generate a Create + Comments

	panic("this piece of code needs to be updated to make sure that the identities " +
		"are properly commit before usage. That is, generateRandomPersons() need to be called.")

	rand.Seed(seed)
	fake.Seed(seed)

	result := make([]*bug.OperationPack, packNumber)

	for i := 0; i < packNumber; i++ {
		opp := &bug.OperationPack{}

		var op bug.Operation

		op = bug.NewCreateOp(
			randomPerson(),
			time.Now().Unix(),
			fake.Sentence(),
			paragraphs(),
			nil,
		)

		opp.Append(op)

		for j := 0; j < opNumber-1; j++ {
			op = bug.NewAddCommentOp(
				randomPerson(),
				time.Now().Unix(),
				paragraphs(),
				nil,
			)
			opp.Append(op)
		}

		result[i] = opp
	}

	return result
}

func person(repo repository.RepoClock) (*identity.Identity, error) {
	return identity.NewIdentity(repo, fake.FullName(), fake.EmailAddress())
}

var persons []*identity.Identity

func generateRandomPersons(repo repository.ClockedRepo, n int) {
	persons = make([]*identity.Identity, n)
	for i := range persons {
		p, err := person(repo)
		if err != nil {
			panic(err)
		}
		err = p.Commit(repo)
		if err != nil {
			panic(err)
		}
		persons[i] = p
	}
}

func randomPerson() identity.Interface {
	index := rand.Intn(len(persons))
	return persons[index]
}

func paragraphs() string {
	p := fake.Paragraphs()
	return strings.Replace(p, "\t", "\n\n", -1)
}

func comment(b bug.Interface, p identity.Interface, timestamp int64) {
	_, _ = bug.AddComment(b, p, timestamp, paragraphs())
}

func title(b bug.Interface, p identity.Interface, timestamp int64) {
	_, _ = bug.SetTitle(b, p, timestamp, fake.Sentence())
}

func open(b bug.Interface, p identity.Interface, timestamp int64) {
	_, _ = bug.Open(b, p, timestamp)
}

func close(b bug.Interface, p identity.Interface, timestamp int64) {
	_, _ = bug.Close(b, p, timestamp)
}

var addedLabels []string

func labels(b bug.Interface, p identity.Interface, timestamp int64) {
	var removed []string
	nbRemoved := rand.Intn(3)
	for nbRemoved > 0 && len(addedLabels) > 0 {
		index := rand.Intn(len(addedLabels))
		removed = append(removed, addedLabels[index])
		addedLabels[index] = addedLabels[len(addedLabels)-1]
		addedLabels = addedLabels[:len(addedLabels)-1]
		nbRemoved--
	}

	var added []string
	nbAdded := rand.Intn(3)
	for i := 0; i < nbAdded; i++ {
		label := fake.Word()
		added = append(added, label)
		addedLabels = append(addedLabels, label)
	}

	// ignore error
	// if the randomisation produce no changes, no op
	// is added to the bug
	_, _, _ = bug.ChangeLabels(b, p, timestamp, added, removed)
}