Skip to content

Commit

Permalink
Fix for lookup table corruption.
Browse files Browse the repository at this point in the history
Issue occurred when the same experiment name used in different
collections.  When one of those experiments renamed, updates meant to
rename the experiment referenced by child channels also updated
the experiments with the same name, in the lookup table.  Lookup table
query now also filters on the collection name to ensure updates are
isolated to the renamed experiment's channels.
  • Loading branch information
movestill committed Apr 24, 2017
1 parent 337d347 commit e848482
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
5 changes: 3 additions & 2 deletions django/bosscore/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ def update_lookup_experiment(lookup_key, boss_key, collection_name, experiment_n


# update all channels that reference this experiment
all_lookup_objs = BossLookup.objects.filter(experiment_name=old_experiment_name).exclude(
lookup_key=lookup_key)
all_lookup_objs = BossLookup.objects.filter(
collection_name=collection_name, experiment_name=old_experiment_name).exclude(
lookup_key=lookup_key)
for item in all_lookup_objs:

split_key = item.boss_key.split('&')
Expand Down
28 changes: 27 additions & 1 deletion django/bosscore/test/setup_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,41 @@ def create_group(self, group_name):
def insert_test_data(self):

self.add_collection('col1', 'Description for collection1')
self.add_collection('col1-22', 'Description for collection1')
self.add_collection('col1-22', 'Description for collection1-22')
self.add_collection('col2', 'Description for collection2')

self.add_coordinate_frame('cf1', 'Description for cf1', 0, 1000, 0, 1000, 0, 1000, 4, 4, 4)

self.add_experiment('col1', 'exp1', 'cf1', 10, 10, 1)
self.add_experiment('col1', 'exp22', 'cf1', 10, 500, 1)

self.add_channel('col1', 'exp1', 'channel1', 0, 0, 'uint8', 'image')
self.add_channel('col1', 'exp1', 'channel2', 0, 0, 'uint8', 'image')
self.add_channel('col1', 'exp1', 'channel3', 0, 0, 'uint64', 'annotation', ['channel1'])
self.add_channel('col1', 'exp1', 'layer1', 0, 0, 'uint64', 'annotation', ['channel1'])

def insert_lookup_test_data(self):
"""
Test data for LookupTest test case.
"""

self.add_collection('col1', 'Description for collection1')
self.add_collection('col2', 'Description for collection2')

self.add_coordinate_frame('cf1', 'Description for cf1', 0, 1000, 0, 1000, 0, 1000, 4, 4, 4)

self.add_experiment('col1', 'exp1', 'cf1', 10, 10, 1)

# This experiment is _purposed_ named the same as the exp in col1.
# Ensuring that renaming an experiment does not affect experiments with
# the same name in other collections.
self.add_experiment('col2', 'exp1', 'cf1', 10, 500, 1)

self.add_channel('col1', 'exp1', 'channel1', 0, 0, 'uint8', 'image')
self.add_channel('col1', 'exp1', 'channel2', 0, 0, 'uint8', 'image')
self.add_channel('col1', 'exp1', 'channel3', 0, 0, 'uint64', 'annotation', ['channel1'])
self.add_channel('col1', 'exp1', 'layer1', 0, 0, 'uint64', 'annotation', ['channel1'])
self.add_channel('col2', 'exp1', 'channel1', 0, 0, 'uinit8', 'image')

def insert_spatialdb_test_data(self):

Expand Down
57 changes: 57 additions & 0 deletions django/bosscore/test/test_lookup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2016 The Johns Hopkins University Applied Physics Laboratory
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from bosscore.lookup import LookUpKey
from bosscore.models import Collection, Experiment, Channel
from bosscore.models import BossLookup
from rest_framework.test import APITestCase
from .setup_db import SetupTestDB
import unittest


class LookupTest(APITestCase):
def setUp(self):
dbsetup = SetupTestDB()
user = dbsetup.create_user('testuser')
dbsetup.add_role('resource-manager')
dbsetup.set_user(user)

self.client.force_login(user)
dbsetup.insert_lookup_test_data()

def test_update_lookup_experiment(self):
"""
On an experiment rename, make sure only resources that are children of
the experiment are changed.
This is a regression test.
"""
new_exp_name = 'new_exp'
collection = 'col2'
orig_exp_name = 'exp1'

collection_obj = Collection.objects.get(name=collection)
experiment_obj = Experiment.objects.get(name=orig_exp_name, collection=collection_obj)
lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk)
boss_key = collection_obj.name + '&' + new_exp_name

# Method under test.
LookUpKey.update_lookup_experiment(
lookup_key, boss_key, collection_obj.name, new_exp_name)

# There should be still 5 rows in the lookup table with orig_exp_name
# as the experiment name under col1. There should be the experiment
# and 4 channels.
all_lookup_objs = BossLookup.objects.filter(experiment_name=orig_exp_name)
self.assertEqual(5, len(all_lookup_objs))

0 comments on commit e848482

Please sign in to comment.