Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ def depsolve(request, unsolved, desired_versions, environment_constraints, cookb
new_unsolved = unsolved[1..-1]

# Pick this cookbook, and add dependencies
cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
cookbook_obj = cookbook_obj_cache.dig(solve_for, desired_version) ||
FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ["cookbooks", solve_for, desired_version]))
cookbook_obj_cache[solve_for] ||= {}
cookbook_obj_cache[solve_for][desired_version] = cookbook_obj
cookbook_metadata = cookbook_obj["metadata"] || {}
Expand All @@ -110,7 +111,8 @@ def depsolve(request, unsolved, desired_versions, environment_constraints, cookb
next if dep_not_found

# Depsolve children with this desired version! First solution wins.
result, cookbook_obj_cache = depsolve(request, new_unsolved, new_desired_versions, environment_constraints, cookbook_obj_cache)
result, returned_cache = depsolve(request, new_unsolved, new_desired_versions, environment_constraints, cookbook_obj_cache)
cookbook_obj_cache = returned_cache || cookbook_obj_cache
return [result, cookbook_obj_cache] if result
end
[nil, nil]
Expand Down
36 changes: 36 additions & 0 deletions spec/endpoints/environment_cookbook_versions_endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,42 @@ def cookbook_json(name, version, dependencies = {})
expect(result).to be_nil
end

it "uses cached cookbook data instead of re-fetching during backtracking" do
desired = {
"web" => ["1.0.0", "2.0.0"],
"db" => ["1.0.0"],
}
# web 2.0.0 depends on lib, which depends on missing (doesn't exist) → branch fails
# web 1.0.0 has no deps → backtracks here, db must be re-solved
# db 1.0.0 should be fetched only once (cached from the first branch)
allow(data_store).to receive(:get)
.with(org_prefix + ["cookbooks", "web", "2.0.0"], request)
.and_return(cookbook_json("web", "2.0.0", { "lib" => ">= 1.0.0" }))
allow(data_store).to receive(:get)
.with(org_prefix + ["cookbooks", "web", "1.0.0"], request)
.and_return(cookbook_json("web", "1.0.0"))
expect(data_store).to receive(:get)
.with(org_prefix + ["cookbooks", "db", "1.0.0"], request)
.once
.and_return(cookbook_json("db", "1.0.0"))
allow(data_store).to receive(:exists_dir?)
.with(org_prefix + %w{cookbooks lib})
.and_return(true)
allow(data_store).to receive(:list)
.with(org_prefix + %w{cookbooks lib})
.and_return(["1.0.0"])
allow(data_store).to receive(:get)
.with(org_prefix + ["cookbooks", "lib", "1.0.0"], request)
.and_return(cookbook_json("lib", "1.0.0", { "missing" => ">= 1.0.0" }))
allow(data_store).to receive(:exists_dir?)
.with(org_prefix + %w{cookbooks missing})
.and_return(false)

result, _cache = endpoint.depsolve(request, %w{web db}, desired, {})
expect(result["web"]).to eq(["1.0.0"])
expect(result["db"]).to eq(["1.0.0"])
end

it "resolves a deep dependency chain" do
desired = { "app" => ["1.0.0"] }
allow(data_store).to receive(:get)
Expand Down
Loading