0

I am writing a django-nose test to test feature for document uploading. In the test I mock new document using SimpleUploadedFile() from django.core.files.uploadedfile. The problem is that the file associated with the document instance cannot be deleted on Windows (test passes on Linux). I get the following error:

in auto_delete_file_on_delete()->
os.remove(instance.document.path)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: 

Here's my test:

def test_delete_doc(self):
    self.client.login(username='xx', password='xx')
    dir_path = os.getcwd()
    manager_user = User.objects.get(username='xx')

    file_name = "test_document"
    file_path = os.path.join(dir_path, file_name)
    new_file = open(file_path, "w")
    new_file.write("Some file content")
    new_file.close()
    new_file = open(os.path.join(dir_path, file_name), "rb")
    new_doc = SimpleUploadedFile(name=file_name, content=new_file.read())
    new_file.close()
    self.client.post(reverse('view_upload'),
                     {'employee_id': manager_user.profile.employee.empId, 'document': new_doc})
    self.assertEqual(len(Document.objects.all()), 1)
    self.client.post(reverse('delete'), {'file_id': Document.objects.all().first().pk})
    self.assertEqual(len(Document.objects.all()), 0)

My view (reverse('delete') refers to delete_document()):

def delete_document(request):
    instance = Document.objects.get(doc_id=request.POST['file_id'])
    instance.delete()
    return redirect('view_upload')

And the signal attached to the instance removal:

@receiver(models.signals.post_delete, sender=Document)
def auto_delete_file_on_delete(sender, instance, **kwargs):
    if instance.document:
        if os.path.isfile(instance.document.path):
            os.remove(instance.document.path)

Does anyone have any ideas why that is happening?

I already tried (getting same error):

  1. Using with to open/close the file.
  2. Using os.open()/os.read()/os.close() to deal with the file.
  3. Removing SimpleUploadedFile() and simply using new_doc = open() to open the file and pass it to the POST request.

Thanks!

Laurynas Tamulevičius
  • 1,479
  • 1
  • 11
  • 25

1 Answers1

0

SimpleUploadedFile is in-memory so it should not matter, and there is nothing too bad in the code you posted. Does view_upload, Document.save() or something else that writes the file to disk close it?

It works on Linux because you can delete an open file.

menesis
  • 371
  • 3
  • 4