1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-09-30 19:22:09 +00:00
forgejo-runner/act/artifactcache/mock_caches.go

226 lines
4.6 KiB
Go
Raw Normal View History

// Code generated by mockery v2.53.5. DO NOT EDIT.
package artifactcache
import (
http "net/http"
bolthold "github.com/timshannon/bolthold"
io "io"
mock "github.com/stretchr/testify/mock"
time "time"
)
// mockCaches is an autogenerated mock type for the caches type
type mockCaches struct {
mock.Mock
}
fix: allow GC & cache operations to operate concurrently (#1040) Fixes #1039. Rather than opening and closing the Bolt DB instance constantly, the cache now maintains one open `*bolthold.Store` for its lifetime, allowing GC, cache read, and cache write operations to occur concurrently. The major risk is this change is, "is it safe to use one Bolt instance across goroutines concurrently?" [Bolt does document its concurrency requirements](https://github.com/boltdb/bolt?tab=readme-ov-file#transactions), and an analysis of our DB interactions looks to me like it introduces very little risk. Most of the cache operations perform multiple touches to the database; for example `useCache` performs a read to fetch a cache object, and then an update to set its `UsedAt` timestamp. If we wanted to ensure consistency in these operations, they should use a Bolt ReadWrite transaction -- but concurrent access would just be setting the field to the same value anyway. The `gcCache` is the complex operation where a transaction might be warranted -- but doing so would also cause the same bug that #1039 indicates. I believe it is safe to run without a transaction because it is protected by an application-level mutex (to prevent multiple concurrent GCs), it is the only code that performs deletes from the database -- these should guarantee that all its delete attempts are successful. In the event of unexpected failure to do the DB write, `gcCache` deletes from the storage before deleting from the DB, so it should just attempt to cleanup again next run. <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/1040): <!--number 1040 --><!--line 0 --><!--description Zml4OiBhbGxvdyBHQyAmIGNhY2hlIG9wZXJhdGlvbnMgdG8gb3BlcmF0ZSBjb25jdXJyZW50bHk=-->fix: allow GC & cache operations to operate concurrently<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1040 Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-30 19:12:45 +00:00
// close provides a mock function with no fields
func (_m *mockCaches) close() {
_m.Called()
}
// commit provides a mock function with given fields: id, size
func (_m *mockCaches) commit(id uint64, size int64) (int64, error) {
ret := _m.Called(id, size)
if len(ret) == 0 {
panic("no return value specified for commit")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(uint64, int64) (int64, error)); ok {
return rf(id, size)
}
if rf, ok := ret.Get(0).(func(uint64, int64) int64); ok {
r0 = rf(id, size)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(uint64, int64) error); ok {
r1 = rf(id, size)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// exist provides a mock function with given fields: id
func (_m *mockCaches) exist(id uint64) (bool, error) {
ret := _m.Called(id)
if len(ret) == 0 {
panic("no return value specified for exist")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(uint64) (bool, error)); ok {
return rf(id)
}
if rf, ok := ret.Get(0).(func(uint64) bool); ok {
r0 = rf(id)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(uint64) error); ok {
r1 = rf(id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// gcCache provides a mock function with no fields
func (_m *mockCaches) gcCache() {
_m.Called()
}
fix: allow GC & cache operations to operate concurrently (#1040) Fixes #1039. Rather than opening and closing the Bolt DB instance constantly, the cache now maintains one open `*bolthold.Store` for its lifetime, allowing GC, cache read, and cache write operations to occur concurrently. The major risk is this change is, "is it safe to use one Bolt instance across goroutines concurrently?" [Bolt does document its concurrency requirements](https://github.com/boltdb/bolt?tab=readme-ov-file#transactions), and an analysis of our DB interactions looks to me like it introduces very little risk. Most of the cache operations perform multiple touches to the database; for example `useCache` performs a read to fetch a cache object, and then an update to set its `UsedAt` timestamp. If we wanted to ensure consistency in these operations, they should use a Bolt ReadWrite transaction -- but concurrent access would just be setting the field to the same value anyway. The `gcCache` is the complex operation where a transaction might be warranted -- but doing so would also cause the same bug that #1039 indicates. I believe it is safe to run without a transaction because it is protected by an application-level mutex (to prevent multiple concurrent GCs), it is the only code that performs deletes from the database -- these should guarantee that all its delete attempts are successful. In the event of unexpected failure to do the DB write, `gcCache` deletes from the storage before deleting from the DB, so it should just attempt to cleanup again next run. <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/1040): <!--number 1040 --><!--line 0 --><!--description Zml4OiBhbGxvdyBHQyAmIGNhY2hlIG9wZXJhdGlvbnMgdG8gb3BlcmF0ZSBjb25jdXJyZW50bHk=-->fix: allow GC & cache operations to operate concurrently<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1040 Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-30 19:12:45 +00:00
// getDB provides a mock function with no fields
func (_m *mockCaches) getDB() *bolthold.Store {
ret := _m.Called()
if len(ret) == 0 {
fix: allow GC & cache operations to operate concurrently (#1040) Fixes #1039. Rather than opening and closing the Bolt DB instance constantly, the cache now maintains one open `*bolthold.Store` for its lifetime, allowing GC, cache read, and cache write operations to occur concurrently. The major risk is this change is, "is it safe to use one Bolt instance across goroutines concurrently?" [Bolt does document its concurrency requirements](https://github.com/boltdb/bolt?tab=readme-ov-file#transactions), and an analysis of our DB interactions looks to me like it introduces very little risk. Most of the cache operations perform multiple touches to the database; for example `useCache` performs a read to fetch a cache object, and then an update to set its `UsedAt` timestamp. If we wanted to ensure consistency in these operations, they should use a Bolt ReadWrite transaction -- but concurrent access would just be setting the field to the same value anyway. The `gcCache` is the complex operation where a transaction might be warranted -- but doing so would also cause the same bug that #1039 indicates. I believe it is safe to run without a transaction because it is protected by an application-level mutex (to prevent multiple concurrent GCs), it is the only code that performs deletes from the database -- these should guarantee that all its delete attempts are successful. In the event of unexpected failure to do the DB write, `gcCache` deletes from the storage before deleting from the DB, so it should just attempt to cleanup again next run. <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/1040): <!--number 1040 --><!--line 0 --><!--description Zml4OiBhbGxvdyBHQyAmIGNhY2hlIG9wZXJhdGlvbnMgdG8gb3BlcmF0ZSBjb25jdXJyZW50bHk=-->fix: allow GC & cache operations to operate concurrently<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1040 Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-30 19:12:45 +00:00
panic("no return value specified for getDB")
}
var r0 *bolthold.Store
if rf, ok := ret.Get(0).(func() *bolthold.Store); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*bolthold.Store)
}
}
fix: allow GC & cache operations to operate concurrently (#1040) Fixes #1039. Rather than opening and closing the Bolt DB instance constantly, the cache now maintains one open `*bolthold.Store` for its lifetime, allowing GC, cache read, and cache write operations to occur concurrently. The major risk is this change is, "is it safe to use one Bolt instance across goroutines concurrently?" [Bolt does document its concurrency requirements](https://github.com/boltdb/bolt?tab=readme-ov-file#transactions), and an analysis of our DB interactions looks to me like it introduces very little risk. Most of the cache operations perform multiple touches to the database; for example `useCache` performs a read to fetch a cache object, and then an update to set its `UsedAt` timestamp. If we wanted to ensure consistency in these operations, they should use a Bolt ReadWrite transaction -- but concurrent access would just be setting the field to the same value anyway. The `gcCache` is the complex operation where a transaction might be warranted -- but doing so would also cause the same bug that #1039 indicates. I believe it is safe to run without a transaction because it is protected by an application-level mutex (to prevent multiple concurrent GCs), it is the only code that performs deletes from the database -- these should guarantee that all its delete attempts are successful. In the event of unexpected failure to do the DB write, `gcCache` deletes from the storage before deleting from the DB, so it should just attempt to cleanup again next run. <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/1040): <!--number 1040 --><!--line 0 --><!--description Zml4OiBhbGxvdyBHQyAmIGNhY2hlIG9wZXJhdGlvbnMgdG8gb3BlcmF0ZSBjb25jdXJyZW50bHk=-->fix: allow GC & cache operations to operate concurrently<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1040 Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-30 19:12:45 +00:00
return r0
}
// readCache provides a mock function with given fields: id, repo
func (_m *mockCaches) readCache(id uint64, repo string) (*Cache, error) {
ret := _m.Called(id, repo)
if len(ret) == 0 {
panic("no return value specified for readCache")
}
var r0 *Cache
var r1 error
if rf, ok := ret.Get(0).(func(uint64, string) (*Cache, error)); ok {
return rf(id, repo)
}
if rf, ok := ret.Get(0).(func(uint64, string) *Cache); ok {
r0 = rf(id, repo)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*Cache)
}
}
if rf, ok := ret.Get(1).(func(uint64, string) error); ok {
r1 = rf(id, repo)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// serve provides a mock function with given fields: w, r, id
func (_m *mockCaches) serve(w http.ResponseWriter, r *http.Request, id uint64) {
_m.Called(w, r, id)
}
// setgcAt provides a mock function with given fields: at
func (_m *mockCaches) setgcAt(at time.Time) {
_m.Called(at)
}
// useCache provides a mock function with given fields: id
func (_m *mockCaches) useCache(id uint64) error {
ret := _m.Called(id)
if len(ret) == 0 {
panic("no return value specified for useCache")
}
var r0 error
if rf, ok := ret.Get(0).(func(uint64) error); ok {
r0 = rf(id)
} else {
r0 = ret.Error(0)
}
return r0
}
// validateMac provides a mock function with given fields: rundata
func (_m *mockCaches) validateMac(rundata RunData) (string, error) {
ret := _m.Called(rundata)
if len(ret) == 0 {
panic("no return value specified for validateMac")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(RunData) (string, error)); ok {
return rf(rundata)
}
if rf, ok := ret.Get(0).(func(RunData) string); ok {
r0 = rf(rundata)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(RunData) error); ok {
r1 = rf(rundata)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// write provides a mock function with given fields: id, offset, reader
func (_m *mockCaches) write(id uint64, offset uint64, reader io.Reader) error {
ret := _m.Called(id, offset, reader)
if len(ret) == 0 {
panic("no return value specified for write")
}
var r0 error
if rf, ok := ret.Get(0).(func(uint64, uint64, io.Reader) error); ok {
r0 = rf(id, offset, reader)
} else {
r0 = ret.Error(0)
}
return r0
}
// newMockCaches creates a new instance of mockCaches. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func newMockCaches(t interface {
mock.TestingT
Cleanup(func())
},
) *mockCaches {
mock := &mockCaches{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}