class ClientError(OssError):
    def __init__(self, message):
        OssError.__init__(self, OSS_CLIENT_ERROR_STATUS, {}, 'ClientError: ' + message, {})

    def __str__(self):
        return self._str_with_body() class RequestError(OssError):
    def __init__(self, e):
        OssError.__init__(self, OSS_REQUEST_ERROR_STATUS, {}, 'RequestError: ' + str(e), {})
        self.exception = e

    def __str__(self):
        return self._str_with_body() class NoSuchBucket(NotFound):
    status = 404
    code = 'NoSuchBucket' class OpenApiServerError(OssError):
    def __init__(self, status, request_id, message, error_code):
        OssError.__init__(self, status, {OSS_REQUEST_ID : request_id}, '', {'Code': error_code, 'Message': message}) class NotFound(ServerError):
    status = 404
    code = '' class NoSuchKey(NotFound):
    status = 404
    code = 'NoSuchKey' class Conflict(ServerError):
    status = 409
    code = '' class PositionNotEqualToLength(Conflict):
    status = 409
    code = 'PositionNotEqualToLength'

    def __init__(self, status, headers, body, details):
        super(PositionNotEqualToLength, self).__init__(status, headers, body, details)
        self.next_position = int(headers[OSS_NEXT_APPEND_POSITION]) class ObjectNotAppendable(Conflict):
    status = 409
    code = 'ObjectNotAppendable' def to_bytes(data):
def to_string(data):
def to_unicode(data):
def stringify(input):
def to_bytes(data):
def to_string(data):
def to_unicode(data):
def stringify(input): class Tagging(object):

    def __init__(self, tagging_rules=None):
        
        self.tag_set = tagging_rules or TaggingRule() 

    def __str__(self):

        tag_str = ""
        
        tagging_rule = self.tag_set.tagging_rule

        for key in tagging_rule:
            tag_str += key
            tag_str += "#" + tagging_rule[key] + " "

        return tag_str class TaggingRule(object):

    def __init__(self):
        self.tagging_rule = dict()

    def add(self, key, value):

        if key is None or key == '':
            raise ClientError("Tagging key should not be empty")

        if len(key) > _MAX_OBJECT_TAGGING_KEY_LENGTH:
            raise ClientError("Tagging key is too long")

        if len(value) > _MAX_OBJECT_TAGGING_VALUE_LENGTH:
            raise ClientError("Tagging value is too long")

        self.tagging_rule[key] = value

    def delete(self, key):
        del self.tagging_rule[key]

    def len(self):
        return len(self.tagging_rule)

    def to_query_string(self):
        query_string = ''

        for key in self.tagging_rule:
            query_string += urlquote(key)
            query_string += '='
            query_string += urlquote(self.tagging_rule[key])
            query_string += '&'

        if len(query_string) == 0:
            return ''
        else:
            query_string = query_string[:-1]

        return query_string OSS_OBJECT_TAGGING = "x-oss-tagging" OSS_OBJECT_TAGGING_COPY_DIRECTIVE = "x-oss-tagging-directive" def to_bytes(data):
def to_string(data):
def to_unicode(data):
def stringify(input):
def to_bytes(data):
def to_string(data):
def to_unicode(data):
def stringify(input):
import requests
import filecmp
import calendar
import json
import base64
from oss2.exceptions import (ClientError, RequestError, NoSuchBucket, OpenApiServerError,
        NotFound, NoSuchKey, Conflict, PositionNotEqualToLength, ObjectNotAppendable)
from oss2.compat import is_py2, is_py33
from oss2.models import Tagging, TaggingRule
from oss2.headers import OSS_OBJECT_TAGGING, OSS_OBJECT_TAGGING_COPY_DIRECTIVE
from oss2.compat import urlunquote, urlquote, to_bytes, to_string
from .common import *
        from oss2.models import (RestoreJobParameters, RestoreConfiguration, RESTORE_TIER_EXPEDITED,
                                 RESTORE_TIER_STANDARD, RESTORE_TIER_BULK)
        from oss2.models import RestoreJobParameters, RestoreConfiguration
        from oss2.models import RestoreJobParameters, RestoreConfiguration, RESTORE_TIER_BULK
# -*- coding: utf-8 -*-






def now():
    return int(calendar.timegm(time.gmtime()))


class TestObject(OssTestCase):
    def test_object(self):
        key = self.random_key('.js')
        content = random_bytes(1024)

        self.assertRaises(NotFound, self.bucket.head_object, key)

        lower_bound = now() - 60 * 16
        upper_bound = now() + 60 * 16

        def assert_result(result):
            self.assertEqual(result.content_length, len(content))
            self.assertEqual(result.content_type, 'application/javascript')
            self.assertEqual(result.object_type, 'Normal')

            self.assertTrue(result.last_modified > lower_bound)
            self.assertTrue(result.last_modified < upper_bound)

            self.assertTrue(result.etag)

        self.bucket.put_object(key, content)

        get_result = self.bucket.get_object(key)
        self.assertEqual(get_result.read(), content)
        assert_result(get_result)
        self.assertTrue(get_result.client_crc is not None)
        self.assertTrue(get_result.server_crc is not None)
        self.assertTrue(get_result.client_crc == get_result.server_crc)

        head_result = self.bucket.head_object(key)
        assert_result(head_result)

        self.assertEqual(get_result.last_modified, head_result.last_modified)
        self.assertEqual(get_result.etag, head_result.etag)

        self.bucket.delete_object(key)


        self.assertRaises(NoSuchKey, self.bucket.get_object, key)