Javi Martín d2d517059d Fix race condition with ballot lines
With two concurrent requests, it's possible to create two ballot lines
when only one of them should be created.

The reason is the code validating the line is not thread safe:

```
if ballot.amount_available(investment.heading) < investment.price.to_i
  errors.add(:money, "insufficient funds")
end
```

If the second request executes this code after the first request has
executed it but before the first request has saved the record to the
database, both records will pass this validation and both will be saved
to the database.

So we need to introduce a lock. Now when the second request tries to
lock the ballot, it finds it's already locked by the first request, and
will wait for the transaction of the first request to finish before
checking whether there are sufficient funds.

Note we need to disable transactions during the test; otherwise the
second thread will wait for the first one to finish.

Also note that we need to update a couple of tests because records are
reloaded when they're locked.

In one case, reloading the ballot causes `ballot.user` to be `nil`,
since the user is hidden. So we hide the user after creating all its
associated records (which is the scenario that would take place in real
life).

In the other case, reloading the ballot causes `ballot.user` to reload
as well. So we need to reload the user object used in the test too so it
gets the updates done on `ballot.user`.

I haven't been able to reproduce this behavior in a system test. The
following test works with Rails 5.0, but it stopped working when we
moved to system tests in commit 9427f014. After that commit, for reasons
I haven't been able to debug (reintroducing truncation with
DatabaseClaner didn't seem to affect this test, and neither did
increasing the number of threads in Puma), the two AJAX requests
executed here are no longer simultaneous; the second request waits for
the first one to finish.

scenario "Race conditions with simultaneous requests", :js do
  allow_any_instance_of(Budget::Ballot::Line).to receive(:check_sufficient_funds) do |object|
    allow(object).to receive(:check_sufficient_funds).and_call_original
    object.check_sufficient_funds
    sleep 0.3
  end

  ["First", "Second"].each do |title|
    create(:budget_investment, :selected,
      heading: california,
      price:   california.price,
      title:   title
    )
  end

  login_as(user)
  visit budget_investments_path(budget, heading_id: california.id)

  within(".budget-investment", text: "First") { click_link "Vote" }
  within(".budget-investment", text: "Second") { click_link "Vote" }

  expect(page).to have_link "Remove vote"
  expect(Budget::Ballot::Line.count).to eq 1
end
2020-07-12 22:11:40 +02:00
2018-12-07 13:57:32 +01:00
2020-07-12 22:11:40 +02:00
2019-11-06 18:58:05 +07:00
2015-07-15 13:32:13 +02:00
2020-07-12 22:11:40 +02:00
2020-06-16 13:47:38 +02:00
2017-06-14 18:14:02 +02:00
2015-08-17 19:55:28 +02:00
2020-07-08 12:39:25 +02:00
2020-07-08 12:39:25 +02:00
2019-03-15 10:29:07 +01:00
2020-04-28 10:27:30 +02:00
2020-04-28 10:27:30 +02:00
2020-07-12 22:11:40 +02:00
2020-07-08 12:39:25 +02:00
2020-07-08 12:39:25 +02:00

CONSUL logo

CONSUL

Citizen Participation and Open Government Application

Build Status Code Climate Coverage Status Crowdin License: AGPL v3 Reviewed by Hound

Accessibility conformance A11y issues checked with Rocket Validator

Join the chat at https://gitter.im/consul/consul Help wanted

Knapsack Pro Parallel CI builds for RSpec tests

This is the opensource code repository of the eParticipation website CONSUL, originally developed for the Madrid City government eParticipation website

Documentation

Check the ongoing documentation at https://docs.consulproject.org to learn more about how to start your own CONSUL fork, install it, customize it and learn to use it from an administrator/maintainer perspective.

CONSUL Project main website

You can access the main website of the project at http://consulproject.org where you can find documentation about the use of the platform, videos, and links to the community space.

Configuration for development and test environments

NOTE: For more detailed instructions check the docs

Prerequisites: install git, Ruby 2.5.8, bundler gem, Node.js and PostgreSQL (>=9.4).

git clone https://github.com/consul/consul.git
cd consul
bundle install
cp config/database.yml.example config/database.yml
cp config/secrets.yml.example config/secrets.yml
bin/rake db:create
bin/rake db:migrate
bin/rake db:dev_seed
RAILS_ENV=test rake db:setup

Run the app locally:

bin/rails s

Run the tests with:

bin/rspec

You can use the default admin user from the seeds file:

user: admin@consul.dev pass: 12345678

But for some actions like voting, you will need a verified user, the seeds file also includes one:

user: verified@consul.dev pass: 12345678

Configuration for production environments

See installer

Current state

Development started on 2015 July 15th. Code was deployed to production on 2015 september 7th to decide.madrid.es. Since then new features are added often. You can take a look at the current features at the project's website and future features at the Roadmap and open issues list.

License

Code published under AFFERO GPL v3 (see LICENSE-AGPLv3.txt)

Contributions

See CONTRIBUTING.md

Description
This is the repository for a demo instance for Nairobi County
Readme 104 MiB
Languages
Ruby 76.1%
HTML 14.6%
SCSS 5.7%
JavaScript 2.3%
Python 1.2%