Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Add resource offer tests
Browse files Browse the repository at this point in the history
bgins committed Dec 4, 2024
1 parent 80eeea5 commit ad321fa
Showing 1 changed file with 316 additions and 8 deletions.
324 changes: 316 additions & 8 deletions pkg/solver/store/store_test.go
Original file line number Diff line number Diff line change
@@ -316,8 +316,264 @@ func TestJobOfferQuery(t *testing.T) {
}
}

func TestJobOfferConcurrentOps(t *testing.T) {
offers := generateJobOffers(4, 10)
// Resource Offer

func TestResourceOfferOps(t *testing.T) {
storeConfigs := setupStores(t)
for _, config := range storeConfigs {
// Test multiple resource offers in a single test run
t.Run(config.name, func(t *testing.T) {
getStore := config.init()
store := getStore()

// Generate multiple resource offers
resourceOffers := generateResourceOffers(5, 50)

for _, resourceOffer := range resourceOffers {
// Add resource offer
added, err := store.AddResourceOffer(resourceOffer)
if err != nil {
t.Fatalf("Failed to add resource offer: %v", err)
}
if added.ID != resourceOffer.ID {
t.Errorf("Expected ID %s, got %s", resourceOffer.ID, added.ID)
}

// Get resource offer
retrieved, err := store.GetResourceOffer(resourceOffer.ID)
if err != nil {
t.Fatalf("Failed to get resource offer: %v", err)
}
if retrieved == nil {
t.Fatalf("Expected resource offer, got nil")
}
if retrieved.ID != resourceOffer.ID {
t.Errorf("Expected ID %s, got %s", resourceOffer.ID, retrieved.ID)
}

// Get resource offer by address
byAddress, err := store.GetResourceOfferByAddress(resourceOffer.ResourceProvider)
if err != nil {
t.Fatalf("Failed to get resource offer by address: %v", err)
}
if byAddress == nil {
t.Fatalf("Expected resource offer by address, got nil")
}
if byAddress.ResourceProvider != resourceOffer.ResourceProvider {
t.Errorf("Expected provider %s, got %s", resourceOffer.ResourceProvider, byAddress.ResourceProvider)
}

// Update resource offer
newDealID := generateCID()
newState := generateState()

updated, err := store.UpdateResourceOfferState(resourceOffer.ID, newDealID, newState)
if err != nil {
t.Fatalf("Failed to update resource offer state: %v", err)
}
if updated.DealID != newDealID || updated.State != newState {
t.Errorf("Update failed: expected dealID=%s state=%d, got dealID=%s state=%d",
newDealID, newState, updated.DealID, updated.State)
}

// Remove resource offer
err = store.RemoveResourceOffer(resourceOffer.ID)
if err != nil {
t.Fatalf("Failed to remove resource offer: %v", err)
}

// Verify removal
removed, err := store.GetResourceOffer(resourceOffer.ID)
if err != nil {
t.Fatalf("Error checking removed resource offer: %v", err)
}
if removed != nil {
t.Error("Resource offer still exists after removal")
}

// Verify removal by address
removedByAddr, err := store.GetResourceOfferByAddress(resourceOffer.ResourceProvider)
if err != nil {
t.Fatalf("Error checking removed resource offer by address: %v", err)
}
if removedByAddr != nil {
t.Error("Resource offer still exists after removal when checking by address")
}
}
})
}
}

func TestResourceOfferQuery(t *testing.T) {
// Test cases set offer fields relevant to querying.
// All other fields are left with their zero-values.
testCases := []struct {
name string
offers []data.ResourceOfferContainer
query store.GetResourceOffersQuery
expected []string // expected IDs in results
}{
{
name: "filter by resource provider",
offers: []data.ResourceOfferContainer{
{
ID: "QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetDefaultAgreementState(),
},
{
ID: "QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky",
ResourceProvider: "0xabcdef0123456789abcdef0123456789abcdef01",
DealID: "",
State: data.GetDefaultAgreementState(),
},
},
query: store.GetResourceOffersQuery{
ResourceProvider: "0x1234567890123456789012345678901234567890",
},
expected: []string{"QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx"},
},
{
name: "filter not matched offers",
offers: []data.ResourceOfferContainer{
{
ID: "QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "QmZ9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kz",
State: data.GetDefaultAgreementState(),
},
{
ID: "QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetDefaultAgreementState(),
},
},
query: store.GetResourceOffersQuery{
NotMatched: true,
},
expected: []string{"QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky"},
},
{
name: "filter active offers",
offers: []data.ResourceOfferContainer{
{
ID: "QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("DealNegotiating"),
},
{
ID: "QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("DealAgreed"),
},
{
ID: "QmZ9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kz",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("ResultsSubmitted"),
},
{
ID: "QmV9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kv",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("ResultsAccepted"),
},
},
query: store.GetResourceOffersQuery{
Active: true,
},
expected: []string{
"QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx",
"QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky",
},
},
{
name: "combined filters",
offers: []data.ResourceOfferContainer{
{
ID: "QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("DealNegotiating"),
},
{
ID: "QmX9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Ky",
ResourceProvider: "0xabcdef0123456789abcdef0123456789abcdef01",
DealID: "",
State: data.GetAgreementStateIndex("DealNegotiating"),
},
{
ID: "QmZ9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kz",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "QmW9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kw",
State: data.GetAgreementStateIndex("DealNegotiating"),
},
{
ID: "QmV9JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kv",
ResourceProvider: "0x1234567890123456789012345678901234567890",
DealID: "",
State: data.GetAgreementStateIndex("ResultsSubmitted"),
},
},
query: store.GetResourceOffersQuery{
ResourceProvider: "0x1234567890123456789012345678901234567890",
NotMatched: true,
Active: true,
},
expected: []string{"QmY8JwJh3bYDUuAnwfpxwStjUY1nQwyhJJ4SPpdV3bZ9Kx"},
},
}

storeConfigs := setupStores(t)
for _, config := range storeConfigs {
getStore := config.init()

for _, tc := range testCases {
// Test each case in a separate test run
t.Run(fmt.Sprintf("%s/%s", config.name, tc.name), func(t *testing.T) {
store := getStore()

// Add test resource offers
for _, ro := range tc.offers {
_, err := store.AddResourceOffer(ro)
if err != nil {
t.Fatalf("Failed to add resource offer: %v", err)
}
}

// Run query
results, err := store.GetResourceOffers(tc.query)
if err != nil {
t.Fatalf("GetResourceOffers failed: %v", err)
}

// Extract result IDs
resultIDs := make([]string, len(results))
for i, r := range results {
resultIDs[i] = r.ID
}

// Sort both slices for comparison
sort.Strings(resultIDs)
sort.Strings(tc.expected)

if !slices.Equal(resultIDs, tc.expected) {
t.Errorf("Expected results %v, got %v", tc.expected, resultIDs)
}
})
}
}
}

// Concurrency

func TestConcurrentOps(t *testing.T) {
jobOffers := generateJobOffers(4, 10)
resourceOffers := generateResourceOffers(4, 10)

storeConfigs := setupStores(t)
for _, config := range storeConfigs {
@@ -326,17 +582,29 @@ func TestJobOfferConcurrentOps(t *testing.T) {
getStore := config.init()
store := getStore()

// Add offers concurrently
errCh := make(chan error, len(offers))
errCh := make(chan error, len(jobOffers)+len(resourceOffers))
var wg sync.WaitGroup

for _, offer := range offers {
// Add job offers concurrently
for _, offer := range jobOffers {
wg.Add(1)
go func(o data.JobOfferContainer) {
defer wg.Done()
_, err := store.AddJobOffer(o)
if err != nil {
errCh <- err
errCh <- fmt.Errorf("job offer error: %v", err)
}
}(offer)
}

// Add resource offers concurrently
for _, offer := range resourceOffers {
wg.Add(1)
go func(o data.ResourceOfferContainer) {
defer wg.Done()
_, err := store.AddResourceOffer(o)
if err != nil {
errCh <- fmt.Errorf("resource offer error: %v", err)
}
}(offer)
}
@@ -351,8 +619,8 @@ func TestJobOfferConcurrentOps(t *testing.T) {
}
}

// Verify all offers were added
for _, offer := range offers {
// Verify all job offers were added
for _, offer := range jobOffers {
retrieved, err := store.GetJobOffer(offer.ID)
if err != nil {
t.Errorf("Failed to get job offer %s: %v", offer.ID, err)
@@ -364,6 +632,20 @@ func TestJobOfferConcurrentOps(t *testing.T) {
t.Errorf("Retrieved job offer ID mismatch: expected %s, got %s", offer.ID, retrieved.ID)
}
}

// Verify all resource offers were added
for _, offer := range resourceOffers {
retrieved, err := store.GetResourceOffer(offer.ID)
if err != nil {
t.Errorf("Failed to get resource offer %s: %v", offer.ID, err)
}
if retrieved == nil {
t.Errorf("Resource offer %s not found after concurrent add", offer.ID)
}
if retrieved != nil && retrieved.ID != offer.ID {
t.Errorf("Retrieved resource offer ID mismatch: expected %s, got %s", offer.ID, retrieved.ID)
}
}
})
}
}
@@ -378,6 +660,14 @@ func generateCID() string {
return fmt.Sprintf("Qm%44x", randBytes)
}

func generateEthAddress() string {
randBytes := make([]byte, 20)
rand.Read(randBytes)

// Mock eth address
return fmt.Sprintf("0x%40x", randBytes)
}

func generateState() uint8 {
return uint8(rand.Intn(len(data.AgreementState)))
}
@@ -398,3 +688,21 @@ func generateJobOffers(min int, max int) []data.JobOfferContainer {

return offers
}

func generateResourceOffer() data.ResourceOfferContainer {
return data.ResourceOfferContainer{
ID: generateCID(),
ResourceProvider: generateEthAddress(),
}
}

func generateResourceOffers(min int, max int) []data.ResourceOfferContainer {
count := min + rand.Intn(max-min+1)
offers := make([]data.ResourceOfferContainer, count)

for i := 0; i < count; i++ {
offers[i] = generateResourceOffer()
}

return offers
}

0 comments on commit ad321fa

Please sign in to comment.