def validate_args(self, args): """Inserts 'fetcher' function and 'type_names' list into the args namespace @throws InputError if something is wrong with our argument logic { // Word wrapping - follow PEP 8 recommendations "rulers": [ 112, 120 ], "word_wrap": true, "wrap_width": 120, // Whitespace - no tabs, trimming, end files with \n "tab_size": 4, "translate_tabs_to_spaces": true, "ensure_newline_at_eof_on_save": true, } @return possibly changed args""" dsname = "UNSET" if args.operation != self.OP_BUILD: args.scrambling_disabled = True else: dsname = getattr(args, "db-name") sgtdb = ShotgunTestDatabase(sample_name=dsname) if sgtdb.exists(): raise InputError("Dataset named '%s' did already exist - please choose a different one" % dsname) # end # end never scramble outside of build mode # SETUP SCRAMBLER if args.scrambling_disabled: scrambler = lambda r, tn: r else: scrambler = scramble_nested_strings # end scrambler # FIGURE OUT SOURCE AND SETUP TYPES # get rid of list args.source = args.source and args.source[0] or list() if not args.source: # SHOTGUN ######### conn = ProxyShotgunConnection() fac = WriterShotgunTypeFactory(TestShotgunTypeFactory.schema_tree(dsname)) # update schema from DB if args.operation == self.OP_BUILD: fac.update_schema(conn) # end don't wrote in query mode args.fetcher = lambda tn: scrambler(conn.find(tn, list(), fac.schema_by_name(tn).keys()), fac.type_names()) args.type_names = fac.type_names() else: if is_sqlalchemy_url(args.source): # SQLALCHEMY ############ db = SQLProxyShotgunConnection(db_url=args.source) # type-names are lower case for sql tables, so we have to transform the value for comparison args.fetcher = lambda tn: scrambler( db.find(tn, [], ["id"]), db.type_names(), transformer=lambda v: v.lower() ) args.type_names = db.type_names() else: # JSONZ ####### fac = TestShotgunTypeFactory(sample_name=args.source) db = ShotgunTestDatabase(sample_name=args.source) args.fetcher = lambda tn: scrambler(db.records(tn), fac.type_names()) args.type_names = fac.type_names() # end handle value # end handle source return args
def test_factory(self): """Test type-creation features""" fac = TestShotgunTypeFactory() self.failUnlessRaises(NameError, fac.type_by_name, "foo") sgdb = ShotgunTestDatabase(use_records_cache=True) # Create every type info_every = 500 tid = 0 for tid, type_name in enumerate(fac.type_names()): sgtype = fac.type_by_name(type_name) # DEBUG ! - this takes 90s/10s (json/fast) to load ! # It was useful for testing, but probably won't be required to look at all the time ################################## if type_name == "EventLogEntry": continue ################################## assert issubclass(sgtype, ShotgunEntity) assert fac.type_by_name(type_name) is sgtype, "should cache the type" assert len(sgtype.sg_schema) # Query properties with data # To improve load times by factor 3, pickle the files uncompressed # our schema knows more entities than there is data. This is fine, the sg schema is not 100% # well formed if not sgdb.has_records(type_name): continue # end ignore weird entities records = sgdb.records(type_name) # Test very value in each record for rid, record in enumerate(records): entity = sgtype(record["id"], record) assert len(entity.changed_properties()) == 0 for name, descriptor in entity.sg_schema.iteritems(): prop = getattr(entity, name) if not prop.has_value(): # in case of dates, it's okay to get a date at time '0', but we don't check it if not issubclass(descriptor._value_type, sgtypes._ShotgunDateMixin): assert not prop.value(), "no property should return an actual value if it doesn't say so" # end handle value type # end if isinstance(prop, ShotgunEntityProperty): # All values that are attached will be returned, disregarding the declared valid types enode = prop.value() assert enode is None or isinstance(enode, ShotgunEntity) assert_set_entity(entity, prop, enode, descriptor, fac) elif isinstance(prop, ShotgunMultiEntityProperty): value = prop.values() assert isinstance(value, list) assert_set_entity(entity, prop, value, descriptor, fac) else: # The value type is sometimes just our wrapper, which returns the original type # Those are date types value = prop.value() if not isinstance(value, (datetime, date)): assert descriptor._value_type.isinstance(value) assert_set_value(entity, prop, value, descriptor) # end handle assertion # end for each schema entry if rid and rid % info_every == 0: sys.stderr.write("Processed %s record %i/%i\n" % (type_name, rid, len(records))) # end provide info # NOTE: We break here as it should be enough ################################################## # For stress testing, remove this break ! break ################################################## # end for each record # end for each type assert tid