diff --git a/README.md b/README.md index 445457c..e85c79d 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,7 @@ To take advantage of the dev environment that is already configured, you need to Install [Docker](https://docs.docker.com/installation/) -Install Docker Compose -```sh -$ pip install docker-compose -``` +Install [Docker Compose](https://docs.docker.com/compose/install/) Clone the repository. ```sh @@ -24,19 +21,19 @@ $ cp secrets.json.template secrets.json Warm up the MariaDB database. This only needs to be done when the database container doesn't exist yet. This will take ~15 seconds once the image has been pulled. ```sh -$ docker-compose up -d db +$ docker compose up -d db ``` Start the app and run the migrations. ```sh # run the migrations -$ docker-compose run --rm manage migrate +$ docker compose run --rm manage migrate # start the app -$ docker-compose up -d app +$ docker compose up -d app # Optional: add a superuser in order to log in to the admin interface -$ docker-compose run --rm manage createsuperuser +$ docker compose run --rm manage createsuperuser ``` The app should now be viewable at the default location of localhost:8787. @@ -47,21 +44,21 @@ However, if the requirements files change, it is important that you rebuild the ```sh # stop the app -$ docker-compose stop +$ docker compose stop # remove the app container -$ docker-compose rm app test manage +$ docker compose rm app test manage # rebuild the app, manage, and test containers -$ docker-compose build +$ docker compose build # start the app -$ docker-compose up -d app +$ docker compose up -d app ``` #### Developing with Podman and Podman-Compose -Similar to docker and docker-compose, you will need to install, clone the repository and create a `secrets.json`. +Similar to Docker and Docker Compose, you will need to install, clone the repository and create a `secrets.json`. [Install or Enable Podman](https://podman.io/getting-started/installation). @@ -81,10 +78,10 @@ fail on the first run since the database needs time to warm up. ```sh # On the initial run or if the schema changes -$ docker-compose run --rm test --create-db +$ docker compose run --rm test --create-db # Subsequent runs -$ docker-compose run --rm test +$ docker compose run --rm test ``` For podman diff --git a/coda/coda_validate/tests/test_feeds.py b/coda/coda_validate/tests/test_feeds.py index 207facd..89dc0f2 100644 --- a/coda/coda_validate/tests/test_feeds.py +++ b/coda/coda_validate/tests/test_feeds.py @@ -40,11 +40,24 @@ def test_items_chooses_oldest_validate(self): feed.items('') assert 'Item was chosen because it is the oldest' in feed.reason + def test_items_chooses_unverified_validate(self): + oldest = factories.ValidateFactory.create_batch(1, last_verified_status='Unverified', + priority=0) + factories.ValidateFactory.create_batch(18, last_verified_status='Passed', priority=0) + factories.ValidateFactory.create_batch(1, last_verified_status='Unverified', priority=0) + + feed = views.AtomNextNewsFeed() + feed_queryset = feed.items('') + assert len(feed_queryset) == 1 + assert oldest[0].identifier == feed_queryset[0].identifier + assert 'Item was chosen because it is the oldest Unverified' in feed.reason + def test_items_chooses_a_random_validate(self): # Make the last_verified time twice less than the validation period time # to ensure that we always randomly select a Validate object. last_verified = datetime.now() - (settings.VALIDATION_PERIOD * 2) - factories.ValidateFactory.create_batch(30, priority=0, last_verified=last_verified) + factories.ValidateFactory.create_batch(30, priority=0, last_verified=last_verified, + last_verified_status='Passed') feed = views.AtomNextNewsFeed() feed.items('') @@ -52,7 +65,8 @@ def test_items_chooses_a_random_validate(self): def test_items_chooses_unprioritized_validate(self): last_verified = datetime.now() + settings.VALIDATION_PERIOD - factories.ValidateFactory.create_batch(30, priority=0, last_verified=last_verified) + factories.ValidateFactory.create_batch(30, priority=0, last_verified=last_verified, + last_verified_status='Passed') feed = views.AtomNextNewsFeed() feed.items('') diff --git a/coda/coda_validate/views.py b/coda/coda_validate/views.py index 80a0978..2edd98d 100644 --- a/coda/coda_validate/views.py +++ b/coda/coda_validate/views.py @@ -63,31 +63,37 @@ def items(self, obj): if v.exists(): reason += 'Item was chosen because it is the \ oldest prioritized.' - # if set is empty, go with any priority with last_verified older than - # settings.VALIDATION_PERIOD else: - # It might seem natural to use django's built-in random ordering, - # but that technique becomes slow when using large sets - # because 'order by ?' is very expensive against MySQL dbs. - # v = Validate.objects.all().filter( - # last_verified__gte=datetime.datetime.now() - - # settings.VALIDATION_PERIOD - # ).order_by('?') - # instead, let's do this: - # http://elpenia.wordpress.com/2010/05/11/getting-random-objects-from-a-queryset-in-django/ - now = datetime.datetime.now() + # if nothing is prioritized, check for unverified status v = validations.filter( - last_verified__lte=now - settings.VALIDATION_PERIOD - ) + last_verified_status='Unverified').order_by('added') if v.exists(): - random_slice = int(random.random() * v.count()) - v = v[random_slice:] - reason += 'Item was randomly selected and within the \ -past year because there is no prioritized record.' - # if that set has no objects, pick the oldest verified item. + reason += 'Item was chosen because it is the oldest Unverified.' else: - v = validations.order_by('last_verified') - reason += 'Item was chosen because there \ + # if set is empty, go with any priority with last_verified older than + # settings.VALIDATION_PERIOD + # It might seem natural to use django's built-in random ordering, + # but that technique becomes slow when using large sets + # because 'order by ?' is very expensive against MySQL dbs. + # v = Validate.objects.all().filter( + # last_verified__gte=datetime.datetime.now() - + # settings.VALIDATION_PERIOD + # ).order_by('?') + # instead, let's do this: + # http://elpenia.wordpress.com/2010/05/11/getting-random-objects-from-a-queryset-in-django/ + now = datetime.datetime.now() + v = validations.filter( + last_verified__lte=now - settings.VALIDATION_PERIOD + ) + if v.exists(): + random_slice = int(random.random() * v.count()) + v = v[random_slice:] + reason += 'Item was randomly selected and within the \ +past year because there is no prioritized record.' + # if that set has no objects, pick the oldest verified item. + else: + v = validations.order_by('last_verified') + reason += 'Item was chosen because there \ is no prioritized record and it had not been validated in the longest \ duration of time.' self.reason = reason diff --git a/docker-compose.yml b/docker-compose.yml index 716073c..c6daaf4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '2' services: db: image: mariadb:10.4