def test_scenario_A(self): # 1) fetch a full document that is a json document self.coll.upsert("id",{"kettle":"fish"}) doc = self.coll.get("id", GetOptions(timeout=timedelta(seconds=10))) # 2) Make a modification to the content content = doc.content_as[JSONDocument].put("field", "value") # 3) replace the document on the server # not formally allowed syntax - can't mix OptionBlocks and named params result = self.coll.replace(doc.id, content, ReplaceOptions(timeout=timedelta(seconds=10)), cas=doc.cas) result = self.coll.replace(doc.id, content, ReplaceOptions(timeout=timedelta(seconds=10), cas=result.cas)) result = self.coll.replace(doc.id, content, expiry=timedelta(seconds=10), cas=result.cas) # Default params also supported for all methods doc2 = self.coll.get("id", expiry=timedelta(seconds=10)) content2 = doc2.content_as[dict].update({"value": "bar"}) self.coll.replace(doc2.id, content2, cas=doc2.cas, expiry=timedelta(seconds=10)) # I include type annotations and getOrError above to make things clearer, # but it'd be more idiomatic to write this: try: self.coll.get("cheese", GetOptions(replica=True)) self.coll.get("cheese", replica=True) # invalid syntax: self.coll.get("cheese", options=GetOptions(replica=True), replica=True) result = self.coll.get("id", GetOptions(timeout=timedelta(seconds=10))) self.coll.replace(result.id, result.content .put("field", "value") .put("foo", "bar"), cas=result.cas, expiry=timedelta(seconds=10)) except: print("could not get doc")
def test_lookup_in_timeout(self): self.coll.upsert("id", {'someArray': ['wibble', 'gronk']}) # wait till it is there self.try_n_times(10, 1, self.coll.get, "id") # ok, it is there... self.coll.get("id", GetOptions(project=["someArray"], timeout=timedelta(seconds=1.0))) self.assertRaisesRegex(InvalidArgumentException, "Expected timedelta", self.coll.get, "id", GetOptions(project=["someArray"], timeout=456)) sdresult_2 = self.coll.lookup_in("id", (SD.get("someArray"),), LookupInOptions(timeout=timedelta(microseconds=1))) self.assertEqual(['wibble', 'gronk'],sdresult_2.content_as[list](0)) sdresult_2 = self.coll.lookup_in("id", (SD.get("someArray"),), LookupInOptions(timeout=timedelta(seconds=1)), timeout=timedelta(microseconds=1)) self.assertEqual(['wibble', 'gronk'],sdresult_2.content_as[list](0))
def test_get_options(self): result = self.cb.get( self.KEY, GetOptions(timeout=timedelta(seconds=2), with_expiry=False)) self.assertIsNotNone(result.cas) self.assertEqual(result.id, self.KEY) self.assertIsNone(result.expiryTime) self.assertDictEqual(self.CONTENT, result.content_as[dict])
def test_project_bad_project_too_long(self): project = [] for _ in range(17): project.append("something") with self.assertRaisesRegex(InvalidArgumentException, "16 operations or less"): self.coll.get(self.KEY, GetOptions(project=project))
def test_customtimeout(self): #tag::customtimeout[] # SDK 3 custom timeout get_result = collection.get( "mydoc-id", GetOptions(timeout=timedelta(seconds=5))) #tag::test[] self.assertEquals("fish",get_result.content_as[str])
def get_with_opts(): print("\n[kv-get-with-opts]") # tag::kv-get-with-opts[] get_result = hotel_collection.get("hotel-456", GetOptions(with_expiry=True)) # Print some result metadata to the console. print("CAS:", get_result.cas) print("Data: {}".format(get_result.content_as[dict])) print("Expiry time: {}".format(get_result.expiryTime))
def test_mutate_in_expiry(self): if self.is_mock: raise SkipTest("mock doesn't support getting xattrs (like $document.expiry)") cas = self.coll.mutate_in(self.KEY, (SD.upsert("c", "ccc"), SD.replace("b", "XXX"),), MutateInOptions(expiry=timedelta(seconds=1000))).cas self.try_n_times(10, 3, self._cas_matches, self.KEY, cas) result = self.coll.get(self.KEY, GetOptions(with_expiry=True)) expires_in = (result.expiry - datetime.now()).total_seconds() self.assertTrue(0 < expires_in < 1001)
def test_get_with_expiry(self): if self.is_mock: raise SkipTest("mock will not return the expiry in the xaddrs") self.coll.upsert(self.KEY, self.CONTENT, UpsertOptions(expiry=timedelta(seconds=1000))) result = self.coll.get(self.KEY, GetOptions(with_expiry=True)) self.assertIsNotNone(result.expiryTime) self.assertDictEqual(self.CONTENT, result.content_as[dict]) expires_in = (result.expiryTime - datetime.now()).total_seconds() self.assertTrue( 1001 >= expires_in > 0, msg="Expected expires_in {} to be between 1000 and 0".format( expires_in))
def test_project(self): content = {"a": "aaa", "b": "bbb", "c": "ccc"} cas = self.coll.upsert(self.KEY, content).cas def cas_matches(c, new_cas): if new_cas != c.get(self.KEY).cas: raise Exception("nope") self.try_n_times(10, 3, cas_matches, self.coll, cas) result = self.coll.get(self.KEY, GetOptions(project=["a"])) self.assertEqual({"a": "aaa"}, result.content_as[dict]) self.assertIsNotNone(result.cas) self.assertEqual(result.id, self.KEY) self.assertIsNone(result.expiryTime)
def test_deprecated_expiry(self): # PYCBC-999 Deprecate GetResult.expiry() # expiry returned datetime, was replaced by expiryTime which returns # an instant (aka unix timestamp) if self.is_mock: raise SkipTest("mock will not return the expiry in the xaddrs") self.coll.upsert(self.KEY, self.CONTENT, UpsertOptions(expiry=timedelta(seconds=1000))) result = self.coll.get(self.KEY, GetOptions(with_expiry=True)) warnings.resetwarnings() with warnings.catch_warnings(record=True) as w: self.assertIsNotNone(result.expiry) self.assertEqual(len(w), 1) expires_in = (result.expiry - datetime.now()).total_seconds() self.assertTrue( 1001 >= expires_in > 0, msg="Expected expires_in {} to be between 1000 and 0".format( expires_in))
def test_scenario_B(self): """ Scenario B: 1) fetch a document fragment which is a json array with elements 2) make modifications to the content 3) replace the fragment in the original document """ self.coll.upsert("id", {'someArray': ['wibble', 'gronk']}) subdoc = self.coll.get("id", GetOptions(project=["someArray"])) result = None if subdoc: arr = subdoc.content_as[list] arr.append("foo") result = self.coll.mutate_in("id", [SD.upsert("someArray", arr)], MutateInOptions(timeout=timedelta(seconds=10))) self.assertIsInstance(result, MutateInResult) self.assertEqual('None',result.content_as[str](0))
opts = UpsertOptions( durability=ClientDurability(ReplicateTo.ONE, PersistTo.ONE)) result = collection.upsert("document-key", document, opts) # end::obs_durability[] except CouchbaseException as ex: # we expect an exception on local/test host, as Durability requirement # requires appropriately configured cluster pass # tag::get[] result = collection.get("document-key") print(result.content_as[dict]) # end::get[] # tag::get_timeout[] opts = GetOptions(timeout=timedelta(seconds=5)) result = collection.get("document-key", opts) print(result.content_as[dict]) # end::get_timeout[] try: # tag::remove_durability[] # remove document with options result = collection.remove( "document-key", RemoveOptions(cas=12345, durability=ServerDurability(Durability.MAJORITY))) # end::remove_durability[] except CouchbaseException as ex: # we expect an exception here as the CAS value is chosen # for example purposes
# tag::raw_json_encode[] transcoder = RawJSONTranscoder() user = {"name": "John Smith", "age": 27} data = orjson.dumps(user) try: _ = collection.upsert( "john-smith", data, UpsertOptions(transcoder=transcoder)) except (ValueFormatException, CouchbaseException) as ex: traceback.print_exc() # end::raw_json_encode[] # tag::raw_json_decode[] try: get_result = collection.get("john-smith", GetOptions(transcoder=transcoder)) except (ValueFormatException, CouchbaseException) as ex: traceback.print_exc() decoded = orjson.loads(get_result.content) assert decoded == user # end::raw_json_decode[] # tag::raw_string_transcoder[] transcoder = RawStringTranscoder() input_str = "Hello, World!" try: _ = collection.upsert( "key", input_str, UpsertOptions(transcoder=transcoder))
def test_document_expiry_values(self): # per PYCBC-968 # WORKAROUND_EXPIRY_CUTOFF_SECONDS: fifty_years = 50 * 365 * 24 * 60 * 60 # RELATIVE_EXPIRY_CUTOFF_SECONDS: thirty_days = 30 * 24 * 60 * 60 now = int(time.time() - 1.0) ttls = [ fifty_years + 1, fifty_years, thirty_days - 1, thirty_days, now + 60, 60, ] bad_ttls = [ -1, ] verify_expiry = True if self.is_mock: # other tests are skipped because "mock will not return the # expiry in the xaddrs", but we can at least test errors and # the warning added for PYCBC-968. ttls = [fifty_years + 1, fifty_years] verify_expiry = False options = GetOptions(with_expiry=True) for cases in (ttls, bad_ttls): warns = [] for ttl in cases: expiry = timedelta(seconds=ttl) warnings.resetwarnings() with warnings.catch_warnings(record=True) as ws: try: result = self.cb.upsert(self.NOKEY, {"x": "y"}, expiry=expiry) self.assertTrue(result.success) warns = ws except InvalidArgumentException: if ttl not in bad_ttls: raise continue try: result = self.cb.get(self.NOKEY, options) except DocumentNotFoundException: result = DocumentNotFoundException then = int(time.time() + 1.0) if ttl > fifty_years: self.assertEqual(len(warns), 1) # ttl taken as expiry time if verify_expiry and ttl > now: self.assertTrue( int(result.expiryTime.timestamp()) == ttl) else: # doc expired immediately self.assertTrue(result is DocumentNotFoundException) else: self.assertEqual(len(warns), 0) if verify_expiry: # ttl >= 30 days (and <= 50 yrs) changed to a timestamp # on the client; server interprets ttl < 30 as a true # duration. Either way expiryTime is a timestamp. self.assertTrue( now + ttl <= int(result.expiryTime.timestamp()) <= then + ttl)
def cas_matches(c, new_cas): r = c.get(self.KEY, GetOptions(with_expiry=True)) if r.cas == new_cas: return r raise Exception("nope")
def test_project_bad_project_string(self): with self.assertRaises(InvalidArgumentException): self.coll.get(self.KEY, GetOptions(project="something"))
def test_project_bad_path(self): result = self.coll.get(self.KEY, GetOptions(project=["some", "qzx"])) self.assertTrue(result.success) with self.assertRaisesRegex(PathNotFoundException, 'qzx'): result.content_as[dict]