void container_test_base::check_public_access(azure::storage::blob_container_public_access_type access)
{
    auto blob = m_container.get_block_blob_reference(_XPLATSTR("blob"));
    blob.upload_text(_XPLATSTR("test"), azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);

    azure::storage::cloud_blob_container public_container(m_container.uri());
    auto public_blob = public_container.get_blob_reference(blob.name());

    if (access != azure::storage::blob_container_public_access_type::off)
    {
        public_blob.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
    }
    else
    {
        CHECK_THROW(public_blob.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception);
    }

    if (access == azure::storage::blob_container_public_access_type::container)
    {
        public_container.list_blobs_segmented(utility::string_t(), true, azure::storage::blob_listing_details::all, 0, azure::storage::continuation_token(), azure::storage::blob_request_options(), m_context);
        public_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
    }
    else
    {
        CHECK_THROW(public_container.list_blobs_segmented(utility::string_t(), true, azure::storage::blob_listing_details::all, 0, azure::storage::continuation_token(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception);
        CHECK_THROW(public_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context), azure::storage::storage_exception);
    }

    auto perms = m_container.download_permissions(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
    CHECK(access == perms.public_access());
}
    TEST_FIXTURE(file_directory_test_base, directory_metadata)
    {
        auto value1 = this->get_random_string();
        auto value2 = this->get_random_string();
        auto value3 = this->get_random_string();
        auto value4 = this->get_random_string();

        // create 2 pairs
        m_directory.metadata()[_XPLATSTR("key1")] = value1;
        m_directory.metadata()[_XPLATSTR("key2")] = value2;
        m_directory.create_if_not_exists(azure::storage::file_access_condition(), azure::storage::file_request_options(), m_context);
        CHECK_UTF8_EQUAL(m_directory.metadata()[_XPLATSTR("key1")], value1);
        CHECK_UTF8_EQUAL(m_directory.metadata()[_XPLATSTR("key2")], value2);

        auto same_directory = m_directory.get_parent_share_reference().get_directory_reference(m_directory.name());
        CHECK(same_directory.metadata().empty());
        same_directory.download_attributes();
        CHECK_EQUAL(2U, same_directory.metadata().size());
        CHECK_UTF8_EQUAL(value1, same_directory.metadata()[_XPLATSTR("key1")]);
        CHECK_UTF8_EQUAL(value2, same_directory.metadata()[_XPLATSTR("key2")]);

        // add 1 pair
        m_directory.metadata()[_XPLATSTR("key3")] = value3;
        m_directory.upload_metadata(azure::storage::file_access_condition(), azure::storage::file_request_options(), m_context);

        same_directory.metadata().clear();
        CHECK(same_directory.metadata().empty());
        same_directory.download_attributes();
        CHECK_EQUAL(3U, same_directory.metadata().size());
        CHECK_UTF8_EQUAL(value1, same_directory.metadata()[_XPLATSTR("key1")]);
        CHECK_UTF8_EQUAL(value2, same_directory.metadata()[_XPLATSTR("key2")]);
        CHECK_UTF8_EQUAL(value3, same_directory.metadata()[_XPLATSTR("key3")]);

        // overwrite with 1 pair
        m_directory.metadata().clear();
        m_directory.metadata()[_XPLATSTR("key4")] = value4;
        m_directory.upload_metadata(azure::storage::file_access_condition(), azure::storage::file_request_options(), m_context);

        same_directory.metadata().clear();
        CHECK(same_directory.metadata().empty());
        same_directory.download_attributes();
        CHECK_EQUAL(1U, same_directory.metadata().size());
        CHECK_UTF8_EQUAL(value4, same_directory.metadata()[_XPLATSTR("key4")]);

        // clear metadata
        m_directory.metadata().clear();
        m_directory.upload_metadata(azure::storage::file_access_condition(), azure::storage::file_request_options(), m_context);

        same_directory.metadata().clear();
        CHECK(same_directory.metadata().empty());
        same_directory.download_attributes();
        CHECK_EQUAL(0U, same_directory.metadata().size());
    }
    TEST_FIXTURE(append_blob_test_base, append_blob_create_with_metadata)
    {
        m_blob.metadata()[U("key1")] = U("value1");
        m_blob.metadata()[U("key2")] = U("value2");
        m_blob.create_or_replace(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);

        auto same_blob = m_container.get_append_blob_reference(m_blob.name());
        CHECK(same_blob.metadata().empty());
        same_blob.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        CHECK_EQUAL(2U, same_blob.metadata().size());
        CHECK_UTF8_EQUAL(U("value1"), same_blob.metadata()[U("key1")]);
        CHECK_UTF8_EQUAL(U("value2"), same_blob.metadata()[U("key2")]);
    }
    TEST_FIXTURE(container_test_base, container_metadata)
    {
        // Create with 2 pairs
        m_container.metadata()[_XPLATSTR("key1")] = _XPLATSTR("value1");
        m_container.metadata()[_XPLATSTR("key2")] = _XPLATSTR("value2");
        m_container.create(azure::storage::blob_container_public_access_type::off, azure::storage::blob_request_options(), m_context);
        check_container_no_stale_property(m_container);

        auto same_container = m_client.get_container_reference(m_container.name());
        CHECK(same_container.metadata().empty());
        same_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        CHECK_EQUAL(2U, same_container.metadata().size());
        CHECK_UTF8_EQUAL(_XPLATSTR("value1"), same_container.metadata()[_XPLATSTR("key1")]);
        CHECK_UTF8_EQUAL(_XPLATSTR("value2"), same_container.metadata()[_XPLATSTR("key2")]);

        // Add 1 pair
        same_container.metadata()[_XPLATSTR("key3")] = _XPLATSTR("value3");
        same_container.upload_metadata(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        m_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        CHECK_EQUAL(3U, same_container.metadata().size());
        CHECK_UTF8_EQUAL(_XPLATSTR("value1"), m_container.metadata()[_XPLATSTR("key1")]);
        CHECK_UTF8_EQUAL(_XPLATSTR("value2"), m_container.metadata()[_XPLATSTR("key2")]);
        CHECK_UTF8_EQUAL(_XPLATSTR("value3"), m_container.metadata()[_XPLATSTR("key3")]);

        // Overwrite with 1 pair
        m_container.metadata().clear();
        m_container.metadata()[_XPLATSTR("key4")] = _XPLATSTR("value4");
        m_container.upload_metadata(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        same_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        CHECK_EQUAL(1U, same_container.metadata().size());
        CHECK_UTF8_EQUAL(_XPLATSTR("value4"), same_container.metadata()[_XPLATSTR("key4")]);

        // Clear all pairs
        same_container.metadata().clear();
        same_container.upload_metadata(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        m_container.download_attributes(azure::storage::access_condition(), azure::storage::blob_request_options(), m_context);
        CHECK(m_container.metadata().empty());
    }