Best Python code snippet using tempest_python
shares_client.py
Source:shares_client.py  
...64        if share_type_id:65            post_body["share"]["share_type"] = share_type_id66        body = json.dumps(post_body)67        resp, body = self.post("shares", body)68        self.expected_success(200, resp.status)69        return self._parse_resp(body)70    def delete_share(self, share_id):71        resp, body = self.delete("shares/%s" % share_id)72        self.expected_success(202, resp.status)73        return body74    def manage_share(self, service_host, protocol, export_path,75                     share_type_id, name=None, description=None):76        post_body = {77            "share": {78                "export_path": export_path,79                "service_host": service_host,80                "protocol": protocol,81                "share_type": share_type_id,82                "name": name,83                "description": description,84            }85        }86        body = json.dumps(post_body)87        resp, body = self.post("os-share-manage", body)88        self.expected_success(200, resp.status)89        return self._parse_resp(body)90    def unmanage_share(self, share_id):91        resp, body = self.post(92            "os-share-unmanage/%s/unmanage" % share_id, None)93        self.expected_success(202, resp.status)94        return body95    def list_shares(self, detailed=False, params=None):96        """Get list of shares w/o filters."""97        uri = 'shares/detail' if detailed else 'shares'98        uri += '?%s' % urlparse.urlencode(params) if params else ''99        resp, body = self.get(uri)100        self.expected_success(200, resp.status)101        return self._parse_resp(body)102    def list_shares_with_detail(self, params=None):103        """Get detailed list of shares w/o filters."""104        return self.list_shares(detailed=True, params=params)105    def get_share(self, share_id):106        resp, body = self.get("shares/%s" % share_id)107        self.expected_success(200, resp.status)108        return self._parse_resp(body)109    def create_access_rule(self, share_id, access_type="ip",110                           access_to="0.0.0.0", access_level=None):111        post_body = {112            "os-allow_access": {113                "access_type": access_type,114                "access_to": access_to,115                "access_level": access_level,116            }117        }118        body = json.dumps(post_body)119        resp, body = self.post("shares/%s/action" % share_id, body)120        self.expected_success(200, resp.status)121        return self._parse_resp(body)122    def list_access_rules(self, share_id):123        body = {"os-access_list": None}124        resp, body = self.post("shares/%s/action" % share_id, json.dumps(body))125        self.expected_success(200, resp.status)126        return self._parse_resp(body)127    def delete_access_rule(self, share_id, rule_id):128        post_body = {129            "os-deny_access": {130                "access_id": rule_id,131            }132        }133        body = json.dumps(post_body)134        resp, body = self.post("shares/%s/action" % share_id, body)135        self.expected_success(202, resp.status)136        return body137    def extend_share(self, share_id, new_size):138        post_body = {139            "os-extend": {140                "new_size": new_size,141            }142        }143        body = json.dumps(post_body)144        resp, body = self.post("shares/%s/action" % share_id, body)145        self.expected_success(202, resp.status)146        return body147    def shrink_share(self, share_id, new_size):148        post_body = {149            "os-shrink": {150                "new_size": new_size,151            }152        }153        body = json.dumps(post_body)154        resp, body = self.post("shares/%s/action" % share_id, body)155        self.expected_success(202, resp.status)156        return body157    def create_snapshot(self, share_id, name=None, description=None,158                        force=False):159        if name is None:160            name = data_utils.rand_name("tempest-created-share-snap")161        if description is None:162            description = data_utils.rand_name(163                "tempest-created-share-snap-desc")164        post_body = {165            "snapshot": {166                "name": name,167                "force": force,168                "description": description,169                "share_id": share_id,170            }171        }172        body = json.dumps(post_body)173        resp, body = self.post("snapshots", body)174        self.expected_success(202, resp.status)175        return self._parse_resp(body)176    def get_snapshot(self, snapshot_id):177        resp, body = self.get("snapshots/%s" % snapshot_id)178        self.expected_success(200, resp.status)179        return self._parse_resp(body)180    def list_snapshots(self, detailed=False, params=None):181        """Get list of share snapshots w/o filters."""182        uri = 'snapshots/detail' if detailed else 'snapshots'183        uri += '?%s' % urlparse.urlencode(params) if params else ''184        resp, body = self.get(uri)185        self.expected_success(200, resp.status)186        return self._parse_resp(body)187    def list_snapshots_with_detail(self, params=None):188        """Get detailed list of share snapshots w/o filters."""189        return self.list_snapshots(detailed=True, params=params)190    def delete_snapshot(self, snap_id):191        resp, body = self.delete("snapshots/%s" % snap_id)192        self.expected_success(202, resp.status)193        return body194    def wait_for_share_status(self, share_id, status):195        """Waits for a share to reach a given status."""196        body = self.get_share(share_id)197        share_name = body['name']198        share_status = body['status']199        start = int(time.time())200        while share_status != status:201            time.sleep(self.build_interval)202            body = self.get_share(share_id)203            share_status = body['status']204            if share_status == status:205                return206            elif 'error' in share_status.lower():207                raise share_exceptions.ShareBuildErrorException(208                    share_id=share_id)209            if int(time.time()) - start >= self.build_timeout:210                message = ('Share %s failed to reach %s status within '211                           'the required time (%s s).' %212                           (share_name, status, self.build_timeout))213                raise exceptions.TimeoutException(message)214    def wait_for_snapshot_status(self, snapshot_id, status):215        """Waits for a snapshot to reach a given status."""216        body = self.get_snapshot(snapshot_id)217        snapshot_name = body['name']218        snapshot_status = body['status']219        start = int(time.time())220        while snapshot_status != status:221            time.sleep(self.build_interval)222            body = self.get_snapshot(snapshot_id)223            snapshot_status = body['status']224            if 'error' in snapshot_status:225                raise share_exceptions.SnapshotBuildErrorException(226                    snapshot_id=snapshot_id)227            if int(time.time()) - start >= self.build_timeout:228                message = ('Share Snapshot %s failed to reach %s status '229                           'within the required time (%s s).' %230                           (snapshot_name, status, self.build_timeout))231                raise exceptions.TimeoutException(message)232    def wait_for_access_rule_status(self, share_id, rule_id, status):233        """Waits for an access rule to reach a given status."""234        rule_status = "new"235        start = int(time.time())236        while rule_status != status:237            time.sleep(self.build_interval)238            rules = self.list_access_rules(share_id)239            for rule in rules:240                if rule["id"] in rule_id:241                    rule_status = rule['state']242                    break243            if 'error' in rule_status:244                raise share_exceptions.AccessRuleBuildErrorException(245                    rule_id=rule_id)246            if int(time.time()) - start >= self.build_timeout:247                message = ('Share Access Rule %s failed to reach %s status '248                           'within the required time (%s s).' %249                           (rule_id, status, self.build_timeout))250                raise exceptions.TimeoutException(message)251    def default_quotas(self, tenant_id):252        resp, body = self.get("os-quota-sets/%s/defaults" % tenant_id)253        self.expected_success(200, resp.status)254        return self._parse_resp(body)255    def show_quotas(self, tenant_id, user_id=None):256        uri = "os-quota-sets/%s" % tenant_id257        if user_id is not None:258            uri += "?user_id=%s" % user_id259        resp, body = self.get(uri)260        self.expected_success(200, resp.status)261        return self._parse_resp(body)262    def reset_quotas(self, tenant_id, user_id=None):263        uri = "os-quota-sets/%s" % tenant_id264        if user_id is not None:265            uri += "?user_id=%s" % user_id266        resp, body = self.delete(uri)267        self.expected_success(202, resp.status)268        return body269    def update_quotas(self, tenant_id, user_id=None, shares=None,270                      snapshots=None, gigabytes=None, snapshot_gigabytes=None,271                      share_networks=None, force=True):272        uri = "os-quota-sets/%s" % tenant_id273        if user_id is not None:274            uri += "?user_id=%s" % user_id275        put_body = {"tenant_id": tenant_id}276        if force:277            put_body["force"] = "true"278        if shares is not None:279            put_body["shares"] = shares280        if snapshots is not None:281            put_body["snapshots"] = snapshots282        if gigabytes is not None:283            put_body["gigabytes"] = gigabytes284        if snapshot_gigabytes is not None:285            put_body["snapshot_gigabytes"] = snapshot_gigabytes286        if share_networks is not None:287            put_body["share_networks"] = share_networks288        put_body = json.dumps({"quota_set": put_body})289        resp, body = self.put(uri, put_body)290        self.expected_success(200, resp.status)291        return self._parse_resp(body)292    def get_limits(self):293        resp, body = self.get("limits")294        self.expected_success(200, resp.status)295        return self._parse_resp(body)296    def is_resource_deleted(self, *args, **kwargs):297        """Verifies whether provided resource deleted or not.298        :param kwargs: dict with expected keys 'share_id', 'snapshot_id',299        :param kwargs: 'sn_id', 'ss_id', 'vt_id' and 'server_id'300        :raises share_exceptions.InvalidResource301        """302        if "share_id" in kwargs:303            if "rule_id" in kwargs:304                rule_id = kwargs.get("rule_id")305                share_id = kwargs.get("share_id")306                rules = self.list_access_rules(share_id)307                for rule in rules:308                    if rule["id"] == rule_id:309                        return False310                return True311            else:312                return self._is_resource_deleted(313                    self.get_share, kwargs.get("share_id"))314        elif "snapshot_id" in kwargs:315            return self._is_resource_deleted(316                self.get_snapshot, kwargs.get("snapshot_id"))317        elif "sn_id" in kwargs:318            return self._is_resource_deleted(319                self.get_share_network, kwargs.get("sn_id"))320        elif "ss_id" in kwargs:321            return self._is_resource_deleted(322                self.get_security_service, kwargs.get("ss_id"))323        elif "vt_id" in kwargs:324            return self._is_resource_deleted(325                self.get_volume_type, kwargs.get("vt_id"))326        elif "st_id" in kwargs:327            return self._is_resource_deleted(328                self.get_share_type, kwargs.get("st_id"))329        elif "server_id" in kwargs:330            return self._is_resource_deleted(331                self.show_share_server, kwargs.get("server_id"))332        else:333            raise share_exceptions.InvalidResource(334                message=six.text_type(kwargs))335    def _is_resource_deleted(self, func, res_id):336        try:337            res = func(res_id)338        except exceptions.NotFound:339            return True340        if res.get('status') in ['error_deleting', 'error']:341            # Resource has "error_deleting" status and can not be deleted.342            resource_type = func.__name__.split('_', 1)[-1]343            raise share_exceptions.ResourceReleaseFailed(344                res_type=resource_type, res_id=res_id)345        return False346    def wait_for_resource_deletion(self, *args, **kwargs):347        """Waits for a resource to be deleted."""348        start_time = int(time.time())349        while True:350            if self.is_resource_deleted(*args, **kwargs):351                return352            if int(time.time()) - start_time >= self.build_timeout:353                raise exceptions.TimeoutException354            time.sleep(self.build_interval)355    def list_extensions(self):356        resp, extensions = self.get("extensions")357        self.expected_success(200, resp.status)358        return self._parse_resp(extensions)359    def update_share(self, share_id, name=None, desc=None, is_public=None):360        body = {"share": {}}361        if name is not None:362            body["share"].update({"display_name": name})363        if desc is not None:364            body["share"].update({"display_description": desc})365        if is_public is not None:366            body["share"].update({"is_public": is_public})367        body = json.dumps(body)368        resp, body = self.put("shares/%s" % share_id, body)369        self.expected_success(200, resp.status)370        return self._parse_resp(body)371    def rename_snapshot(self, snapshot_id, name, desc=None):372        body = {"snapshot": {"display_name": name}}373        if desc is not None:374            body["snapshot"].update({"display_description": desc})375        body = json.dumps(body)376        resp, body = self.put("snapshots/%s" % snapshot_id, body)377        self.expected_success(200, resp.status)378        return self._parse_resp(body)379    def reset_state(self, s_id, status="error", s_type="shares"):380        """Resets the state of a share or a snapshot.381        status: available, error, creating, deleting, error_deleting382        s_type: shares, snapshots383        """384        body = {"os-reset_status": {"status": status}}385        body = json.dumps(body)386        resp, body = self.post("%s/%s/action" % (s_type, s_id), body)387        self.expected_success(202, resp.status)388        return body389    def force_delete(self, s_id, s_type="shares"):390        """Force delete share or snapshot.391        s_type: shares, snapshots392        """393        body = {"os-force_delete": None}394        body = json.dumps(body)395        resp, body = self.post("%s/%s/action" % (s_type, s_id), body)396        self.expected_success(202, resp.status)397        return body398###############399    def list_services(self, params=None):400        """List services."""401        uri = 'os-services'402        if params:403            uri += '?%s' % urlparse.urlencode(params)404        resp, body = self.get(uri)405        self.expected_success(200, resp.status)406        return self._parse_resp(body)407###############408    def _update_metadata(self, share_id, metadata=None, method="post"):409        uri = "shares/%s/metadata" % share_id410        if metadata is None:411            metadata = {}412        post_body = {"metadata": metadata}413        body = json.dumps(post_body)414        if method is "post":415            resp, metadata = self.post(uri, body)416        if method is "put":417            resp, metadata = self.put(uri, body)418        self.expected_success(200, resp.status)419        return self._parse_resp(metadata)420    def set_metadata(self, share_id, metadata=None):421        return self._update_metadata(share_id, metadata)422    def update_all_metadata(self, share_id, metadata=None):423        return self._update_metadata(share_id, metadata, method="put")424    def delete_metadata(self, share_id, key):425        resp, body = self.delete("shares/%s/metadata/%s" % (share_id, key))426        self.expected_success(200, resp.status)427        return body428    def get_metadata(self, share_id):429        resp, body = self.get("shares/%s/metadata" % share_id)430        self.expected_success(200, resp.status)431        return self._parse_resp(body)432###############433    def create_security_service(self, ss_type="ldap", **kwargs):434        # ss_type: ldap, kerberos, active_directory435        # kwargs: name, description, dns_ip, server, domain, user, password436        post_body = {"type": ss_type}437        post_body.update(kwargs)438        body = json.dumps({"security_service": post_body})439        resp, body = self.post("security-services", body)440        self.expected_success(200, resp.status)441        return self._parse_resp(body)442    def update_security_service(self, ss_id, **kwargs):443        # ss_id - id of security-service entity444        # kwargs: dns_ip, server, domain, user, password, name, description445        # for 'active' status can be changed446        # only 'name' and 'description' fields447        body = json.dumps({"security_service": kwargs})448        resp, body = self.put("security-services/%s" % ss_id, body)449        self.expected_success(200, resp.status)450        return self._parse_resp(body)451    def get_security_service(self, ss_id):452        resp, body = self.get("security-services/%s" % ss_id)453        self.expected_success(200, resp.status)454        return self._parse_resp(body)455    def list_security_services(self, detailed=False, params=None):456        uri = "security-services"457        if detailed:458            uri += '/detail'459        if params:460            uri += "?%s" % urlparse.urlencode(params)461        resp, body = self.get(uri)462        self.expected_success(200, resp.status)463        return self._parse_resp(body)464    def delete_security_service(self, ss_id):465        resp, body = self.delete("security-services/%s" % ss_id)466        self.expected_success(202, resp.status)467        return body468###############469    def create_share_network(self, **kwargs):470        # kwargs: name, description471        # + for neutron: neutron_net_id, neutron_subnet_id472        body = json.dumps({"share_network": kwargs})473        resp, body = self.post("share-networks", body)474        self.expected_success(200, resp.status)475        return self._parse_resp(body)476    def update_share_network(self, sn_id, **kwargs):477        # kwargs: name, description478        # + for neutron: neutron_net_id, neutron_subnet_id479        body = json.dumps({"share_network": kwargs})480        resp, body = self.put("share-networks/%s" % sn_id, body)481        self.expected_success(200, resp.status)482        return self._parse_resp(body)483    def get_share_network(self, sn_id):484        resp, body = self.get("share-networks/%s" % sn_id)485        self.expected_success(200, resp.status)486        return self._parse_resp(body)487    def list_share_networks(self):488        resp, body = self.get("share-networks")489        self.expected_success(200, resp.status)490        return self._parse_resp(body)491    def list_share_networks_with_detail(self, params=None):492        """List the details of all shares."""493        uri = "share-networks/detail"494        if params:495            uri += "?%s" % urlparse.urlencode(params)496        resp, body = self.get(uri)497        self.expected_success(200, resp.status)498        return self._parse_resp(body)499    def delete_share_network(self, sn_id):500        resp, body = self.delete("share-networks/%s" % sn_id)501        self.expected_success(202, resp.status)502        return body503###############504    def _map_security_service_and_share_network(self, sn_id, ss_id,505                                                action="add"):506        # sn_id: id of share_network_entity507        # ss_id: id of security service entity508        # action: add, remove509        data = {510            "%s_security_service" % action: {511                "security_service_id": ss_id,512            }513        }514        body = json.dumps(data)515        resp, body = self.post("share-networks/%s/action" % sn_id, body)516        self.expected_success(200, resp.status)517        return self._parse_resp(body)518    def add_sec_service_to_share_network(self, sn_id, ss_id):519        body = self._map_security_service_and_share_network(sn_id, ss_id)520        return body521    def remove_sec_service_from_share_network(self, sn_id, ss_id):522        body = self._map_security_service_and_share_network(523            sn_id, ss_id, "remove")524        return body525    def list_sec_services_for_share_network(self, sn_id):526        resp, body = self.get("security-services?share_network_id=%s" % sn_id)527        self.expected_success(200, resp.status)528        return self._parse_resp(body)529###############530    def list_share_types(self, params=None):531        uri = 'types'532        if params is not None:533            uri += '?%s' % urlparse.urlencode(params)534        resp, body = self.get(uri)535        self.expected_success(200, resp.status)536        return self._parse_resp(body)537    def create_share_type(self, name, is_public=True, **kwargs):538        post_body = {539            'name': name,540            'extra_specs': kwargs.get('extra_specs'),541            'os-share-type-access:is_public': is_public,542        }543        post_body = json.dumps({'share_type': post_body})544        resp, body = self.post('types', post_body)545        self.expected_success(200, resp.status)546        return self._parse_resp(body)547    def delete_share_type(self, share_type_id):548        resp, body = self.delete("types/%s" % share_type_id)549        self.expected_success(202, resp.status)550        return body551    def get_share_type(self, share_type_id):552        resp, body = self.get("types/%s" % share_type_id)553        self.expected_success(200, resp.status)554        return self._parse_resp(body)555    def add_access_to_share_type(self, share_type_id, project_id):556        uri = 'types/%s/action' % share_type_id557        post_body = {'project': project_id}558        post_body = json.dumps({'addProjectAccess': post_body})559        resp, body = self.post(uri, post_body)560        self.expected_success(202, resp.status)561        return body562    def remove_access_from_share_type(self, share_type_id, project_id):563        uri = 'types/%s/action' % share_type_id564        post_body = {'project': project_id}565        post_body = json.dumps({'removeProjectAccess': post_body})566        resp, body = self.post(uri, post_body)567        self.expected_success(202, resp.status)568        return body569    def list_access_to_share_type(self, share_type_id):570        uri = 'types/%s/os-share-type-access' % share_type_id571        resp, body = self.get(uri)572        # [{"share_type_id": "%st_id%", "project_id": "%project_id%"}, ]573        self.expected_success(200, resp.status)574        return self._parse_resp(body)575###############576    def create_share_type_extra_specs(self, share_type_id, extra_specs):577        url = "types/%s/extra_specs" % share_type_id578        post_body = json.dumps({'extra_specs': extra_specs})579        resp, body = self.post(url, post_body)580        self.expected_success(200, resp.status)581        return self._parse_resp(body)582    def get_share_type_extra_spec(self, share_type_id, extra_spec_name):583        uri = "types/%s/extra_specs/%s" % (share_type_id, extra_spec_name)584        resp, body = self.get(uri)585        self.expected_success(200, resp.status)586        return self._parse_resp(body)587    def get_share_type_extra_specs(self, share_type_id, params=None):588        uri = "types/%s/extra_specs" % share_type_id589        if params is not None:590            uri += '?%s' % urlparse.urlencode(params)591        resp, body = self.get(uri)592        self.expected_success(200, resp.status)593        return self._parse_resp(body)594    def update_share_type_extra_spec(self, share_type_id, spec_name,595                                     spec_value):596        uri = "types/%s/extra_specs/%s" % (share_type_id, spec_name)597        extra_spec = {spec_name: spec_value}598        post_body = json.dumps(extra_spec)599        resp, body = self.put(uri, post_body)600        self.expected_success(200, resp.status)601        return self._parse_resp(body)602    def update_share_type_extra_specs(self, share_type_id, extra_specs):603        uri = "types/%s/extra_specs" % share_type_id604        extra_specs = {"extra_specs": extra_specs}605        post_body = json.dumps(extra_specs)606        resp, body = self.post(uri, post_body)607        self.expected_success(200, resp.status)608        return self._parse_resp(body)609    def delete_share_type_extra_spec(self, share_type_id, extra_spec_name):610        uri = "types/%s/extra_specs/%s" % (share_type_id, extra_spec_name)611        resp, body = self.delete(uri)612        self.expected_success(202, resp.status)613        return body614###############615    def list_share_servers(self, search_opts=None):616        """Get list of share servers."""617        uri = "share-servers"618        if search_opts:619            uri += "?%s" % urlparse.urlencode(search_opts)620        resp, body = self.get(uri)621        self.expected_success(200, resp.status)622        return self._parse_resp(body)623    def delete_share_server(self, share_server_id):624        """Delete share server by its ID."""625        uri = "share-servers/%s" % share_server_id626        resp, body = self.delete(uri)627        self.expected_success(202, resp.status)628        return body629    def show_share_server(self, share_server_id):630        """Get share server info."""631        uri = "share-servers/%s" % share_server_id632        resp, body = self.get(uri)633        self.expected_success(200, resp.status)634        return self._parse_resp(body)635    def show_share_server_details(self, share_server_id):636        """Get share server details only."""637        uri = "share-servers/%s/details" % share_server_id638        resp, body = self.get(uri)639        self.expected_success(200, resp.status)640        return self._parse_resp(body)641###############642    def list_pools(self, detail=False, search_opts=None):643        """Get list of scheduler pools."""644        uri = 'scheduler-stats/pools'645        if detail:646            uri += '/detail'647        if search_opts:648            uri += "?%s" % urlparse.urlencode(search_opts)649        resp, body = self.get(uri)650        self.expected_success(200, resp.status)651        return json.loads(body)652###############653    def list_availability_zones(self):654        """Get list of availability zones."""655        uri = 'os-availability-zone'656        resp, body = self.get(uri)657        self.expected_success(200, resp.status)...identity_client.py
Source:identity_client.py  
...34            'password': password35        }36        post_body = json.dumps({'user': post_body})37        resp, body = self.post('users', post_body)38        self.expected_success(201, resp.status)39        body = json.loads(body)40        return service_client.ResponseBody(resp, body['user'])41    def update_user(self, user_id, name, **kwargs):42        """Updates a user."""43        body = self.get_user(user_id)44        email = kwargs.get('email', body['email'])45        en = kwargs.get('enabled', body['enabled'])46        project_id = kwargs.get('project_id', body['project_id'])47        if 'default_project_id' in body.keys():48            default_project_id = kwargs.get('default_project_id',49                                            body['default_project_id'])50        else:51            default_project_id = kwargs.get('default_project_id')52        description = kwargs.get('description', body['description'])53        domain_id = kwargs.get('domain_id', body['domain_id'])54        post_body = {55            'name': name,56            'email': email,57            'enabled': en,58            'project_id': project_id,59            'default_project_id': default_project_id,60            'id': user_id,61            'domain_id': domain_id,62            'description': description63        }64        post_body = json.dumps({'user': post_body})65        resp, body = self.patch('users/%s' % user_id, post_body)66        self.expected_success(200, resp.status)67        body = json.loads(body)68        return service_client.ResponseBody(resp, body['user'])69    def update_user_password(self, user_id, password, original_password):70        """Updates a user password."""71        update_user = {72            'password': password,73            'original_password': original_password74        }75        update_user = json.dumps({'user': update_user})76        resp, _ = self.post('users/%s/password' % user_id, update_user)77        self.expected_success(204, resp.status)78        return service_client.ResponseBody(resp)79    def list_user_projects(self, user_id):80        """Lists the projects on which a user has roles assigned."""81        resp, body = self.get('users/%s/projects' % user_id)82        self.expected_success(200, resp.status)83        body = json.loads(body)84        return service_client.ResponseBodyList(resp, body['projects'])85    def get_users(self, params=None):86        """Get the list of users."""87        url = 'users'88        if params:89            url += '?%s' % parse.urlencode(params)90        resp, body = self.get(url)91        self.expected_success(200, resp.status)92        body = json.loads(body)93        return service_client.ResponseBodyList(resp, body['users'])94    def get_user(self, user_id):95        """GET a user."""96        resp, body = self.get("users/%s" % user_id)97        self.expected_success(200, resp.status)98        body = json.loads(body)99        return service_client.ResponseBody(resp, body['user'])100    def delete_user(self, user_id):101        """Deletes a User."""102        resp, body = self.delete("users/%s" % user_id)103        self.expected_success(204, resp.status)104        return service_client.ResponseBody(resp, body)105    def create_project(self, name, **kwargs):106        """Creates a project."""107        description = kwargs.get('description', None)108        en = kwargs.get('enabled', True)109        domain_id = kwargs.get('domain_id', 'default')110        post_body = {111            'description': description,112            'domain_id': domain_id,113            'enabled': en,114            'name': name115        }116        post_body = json.dumps({'project': post_body})117        resp, body = self.post('projects', post_body)118        self.expected_success(201, resp.status)119        body = json.loads(body)120        return service_client.ResponseBody(resp, body['project'])121    def list_projects(self, params=None):122        url = "projects"123        if params:124            url += '?%s' % parse.urlencode(params)125        resp, body = self.get(url)126        self.expected_success(200, resp.status)127        body = json.loads(body)128        return service_client.ResponseBodyList(resp, body['projects'])129    def update_project(self, project_id, **kwargs):130        body = self.get_project(project_id)131        name = kwargs.get('name', body['name'])132        desc = kwargs.get('description', body['description'])133        en = kwargs.get('enabled', body['enabled'])134        domain_id = kwargs.get('domain_id', body['domain_id'])135        post_body = {136            'id': project_id,137            'name': name,138            'description': desc,139            'enabled': en,140            'domain_id': domain_id,141        }142        post_body = json.dumps({'project': post_body})143        resp, body = self.patch('projects/%s' % project_id, post_body)144        self.expected_success(200, resp.status)145        body = json.loads(body)146        return service_client.ResponseBody(resp, body['project'])147    def get_project(self, project_id):148        """GET a Project."""149        resp, body = self.get("projects/%s" % project_id)150        self.expected_success(200, resp.status)151        body = json.loads(body)152        return service_client.ResponseBody(resp, body['project'])153    def delete_project(self, project_id):154        """Delete a project."""155        resp, body = self.delete('projects/%s' % str(project_id))156        self.expected_success(204, resp.status)157        return service_client.ResponseBody(resp, body)158    def create_role(self, name):159        """Create a Role."""160        post_body = {161            'name': name162        }163        post_body = json.dumps({'role': post_body})164        resp, body = self.post('roles', post_body)165        self.expected_success(201, resp.status)166        body = json.loads(body)167        return service_client.ResponseBody(resp, body['role'])168    def get_role(self, role_id):169        """GET a Role."""170        resp, body = self.get('roles/%s' % str(role_id))171        self.expected_success(200, resp.status)172        body = json.loads(body)173        return service_client.ResponseBody(resp, body['role'])174    def list_roles(self):175        """Get the list of Roles."""176        resp, body = self.get("roles")177        self.expected_success(200, resp.status)178        body = json.loads(body)179        return service_client.ResponseBodyList(resp, body['roles'])180    def update_role(self, name, role_id):181        """Create a Role."""182        post_body = {183            'name': name184        }185        post_body = json.dumps({'role': post_body})186        resp, body = self.patch('roles/%s' % str(role_id), post_body)187        self.expected_success(200, resp.status)188        body = json.loads(body)189        return service_client.ResponseBody(resp, body['role'])190    def delete_role(self, role_id):191        """Delete a role."""192        resp, body = self.delete('roles/%s' % str(role_id))193        self.expected_success(204, resp.status)194        return service_client.ResponseBody(resp, body)195    def assign_user_role(self, project_id, user_id, role_id):196        """Add roles to a user on a project."""197        resp, body = self.put('projects/%s/users/%s/roles/%s' %198                              (project_id, user_id, role_id), None)199        self.expected_success(204, resp.status)200        return service_client.ResponseBody(resp, body)201    def create_domain(self, name, **kwargs):202        """Creates a domain."""203        description = kwargs.get('description', None)204        en = kwargs.get('enabled', True)205        post_body = {206            'description': description,207            'enabled': en,208            'name': name209        }210        post_body = json.dumps({'domain': post_body})211        resp, body = self.post('domains', post_body)212        self.expected_success(201, resp.status)213        body = json.loads(body)214        return service_client.ResponseBody(resp, body['domain'])215    def delete_domain(self, domain_id):216        """Delete a domain."""217        resp, body = self.delete('domains/%s' % str(domain_id))218        self.expected_success(204, resp.status)219        return service_client.ResponseBody(resp, body)220    def list_domains(self):221        """List Domains."""222        resp, body = self.get('domains')223        self.expected_success(200, resp.status)224        body = json.loads(body)225        return service_client.ResponseBodyList(resp, body['domains'])226    def update_domain(self, domain_id, **kwargs):227        """Updates a domain."""228        body = self.get_domain(domain_id)229        description = kwargs.get('description', body['description'])230        en = kwargs.get('enabled', body['enabled'])231        name = kwargs.get('name', body['name'])232        post_body = {233            'description': description,234            'enabled': en,235            'name': name236        }237        post_body = json.dumps({'domain': post_body})238        resp, body = self.patch('domains/%s' % domain_id, post_body)239        self.expected_success(200, resp.status)240        body = json.loads(body)241        return service_client.ResponseBody(resp, body['domain'])242    def get_domain(self, domain_id):243        """Get Domain details."""244        resp, body = self.get('domains/%s' % domain_id)245        self.expected_success(200, resp.status)246        body = json.loads(body)247        return service_client.ResponseBody(resp, body['domain'])248    def get_token(self, resp_token):249        """Get token details."""250        headers = {'X-Subject-Token': resp_token}251        resp, body = self.get("auth/tokens", headers=headers)252        self.expected_success(200, resp.status)253        body = json.loads(body)254        return service_client.ResponseBody(resp, body['token'])255    def delete_token(self, resp_token):256        """Deletes token."""257        headers = {'X-Subject-Token': resp_token}258        resp, body = self.delete("auth/tokens", headers=headers)259        self.expected_success(204, resp.status)260        return service_client.ResponseBody(resp, body)261    def create_group(self, name, **kwargs):262        """Creates a group."""263        description = kwargs.get('description', None)264        domain_id = kwargs.get('domain_id', 'default')265        project_id = kwargs.get('project_id', None)266        post_body = {267            'description': description,268            'domain_id': domain_id,269            'project_id': project_id,270            'name': name271        }272        post_body = json.dumps({'group': post_body})273        resp, body = self.post('groups', post_body)274        self.expected_success(201, resp.status)275        body = json.loads(body)276        return service_client.ResponseBody(resp, body['group'])277    def get_group(self, group_id):278        """Get group details."""279        resp, body = self.get('groups/%s' % group_id)280        self.expected_success(200, resp.status)281        body = json.loads(body)282        return service_client.ResponseBody(resp, body['group'])283    def list_groups(self):284        """Lists the groups."""285        resp, body = self.get('groups')286        self.expected_success(200, resp.status)287        body = json.loads(body)288        return service_client.ResponseBodyList(resp, body['groups'])289    def update_group(self, group_id, **kwargs):290        """Updates a group."""291        body = self.get_group(group_id)292        name = kwargs.get('name', body['name'])293        description = kwargs.get('description', body['description'])294        post_body = {295            'name': name,296            'description': description297        }298        post_body = json.dumps({'group': post_body})299        resp, body = self.patch('groups/%s' % group_id, post_body)300        self.expected_success(200, resp.status)301        body = json.loads(body)302        return service_client.ResponseBody(resp, body['group'])303    def delete_group(self, group_id):304        """Delete a group."""305        resp, body = self.delete('groups/%s' % str(group_id))306        self.expected_success(204, resp.status)307        return service_client.ResponseBody(resp, body)308    def add_group_user(self, group_id, user_id):309        """Add user into group."""310        resp, body = self.put('groups/%s/users/%s' % (group_id, user_id),311                              None)312        self.expected_success(204, resp.status)313        return service_client.ResponseBody(resp, body)314    def list_group_users(self, group_id):315        """List users in group."""316        resp, body = self.get('groups/%s/users' % group_id)317        self.expected_success(200, resp.status)318        body = json.loads(body)319        return service_client.ResponseBodyList(resp, body['users'])320    def list_user_groups(self, user_id):321        """Lists groups which a user belongs to."""322        resp, body = self.get('users/%s/groups' % user_id)323        self.expected_success(200, resp.status)324        body = json.loads(body)325        return service_client.ResponseBodyList(resp, body['groups'])326    def delete_group_user(self, group_id, user_id):327        """Delete user in group."""328        resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))329        self.expected_success(204, resp.status)330        return service_client.ResponseBody(resp, body)331    def assign_user_role_on_project(self, project_id, user_id, role_id):332        """Add roles to a user on a project."""333        resp, body = self.put('projects/%s/users/%s/roles/%s' %334                              (project_id, user_id, role_id), None)335        self.expected_success(204, resp.status)336        return service_client.ResponseBody(resp, body)337    def assign_user_role_on_domain(self, domain_id, user_id, role_id):338        """Add roles to a user on a domain."""339        resp, body = self.put('domains/%s/users/%s/roles/%s' %340                              (domain_id, user_id, role_id), None)341        self.expected_success(204, resp.status)342        return service_client.ResponseBody(resp, body)343    def list_user_roles_on_project(self, project_id, user_id):344        """list roles of a user on a project."""345        resp, body = self.get('projects/%s/users/%s/roles' %346                              (project_id, user_id))347        self.expected_success(200, resp.status)348        body = json.loads(body)349        return service_client.ResponseBodyList(resp, body['roles'])350    def list_user_roles_on_domain(self, domain_id, user_id):351        """list roles of a user on a domain."""352        resp, body = self.get('domains/%s/users/%s/roles' %353                              (domain_id, user_id))354        self.expected_success(200, resp.status)355        body = json.loads(body)356        return service_client.ResponseBodyList(resp, body['roles'])357    def revoke_role_from_user_on_project(self, project_id, user_id, role_id):358        """Delete role of a user on a project."""359        resp, body = self.delete('projects/%s/users/%s/roles/%s' %360                                 (project_id, user_id, role_id))361        self.expected_success(204, resp.status)362        return service_client.ResponseBody(resp, body)363    def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):364        """Delete role of a user on a domain."""365        resp, body = self.delete('domains/%s/users/%s/roles/%s' %366                                 (domain_id, user_id, role_id))367        self.expected_success(204, resp.status)368        return service_client.ResponseBody(resp, body)369    def assign_group_role_on_project(self, project_id, group_id, role_id):370        """Add roles to a user on a project."""371        resp, body = self.put('projects/%s/groups/%s/roles/%s' %372                              (project_id, group_id, role_id), None)373        self.expected_success(204, resp.status)374        return service_client.ResponseBody(resp, body)375    def assign_group_role_on_domain(self, domain_id, group_id, role_id):376        """Add roles to a user on a domain."""377        resp, body = self.put('domains/%s/groups/%s/roles/%s' %378                              (domain_id, group_id, role_id), None)379        self.expected_success(204, resp.status)380        return service_client.ResponseBody(resp, body)381    def list_group_roles_on_project(self, project_id, group_id):382        """list roles of a user on a project."""383        resp, body = self.get('projects/%s/groups/%s/roles' %384                              (project_id, group_id))385        self.expected_success(200, resp.status)386        body = json.loads(body)387        return service_client.ResponseBodyList(resp, body['roles'])388    def list_group_roles_on_domain(self, domain_id, group_id):389        """list roles of a user on a domain."""390        resp, body = self.get('domains/%s/groups/%s/roles' %391                              (domain_id, group_id))392        self.expected_success(200, resp.status)393        body = json.loads(body)394        return service_client.ResponseBodyList(resp, body['roles'])395    def revoke_role_from_group_on_project(self, project_id, group_id, role_id):396        """Delete role of a user on a project."""397        resp, body = self.delete('projects/%s/groups/%s/roles/%s' %398                                 (project_id, group_id, role_id))399        self.expected_success(204, resp.status)400        return service_client.ResponseBody(resp, body)401    def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):402        """Delete role of a user on a domain."""403        resp, body = self.delete('domains/%s/groups/%s/roles/%s' %404                                 (domain_id, group_id, role_id))405        self.expected_success(204, resp.status)406        return service_client.ResponseBody(resp, body)407    def create_trust(self, trustor_user_id, trustee_user_id, project_id,408                     role_names, impersonation, expires_at):409        """Creates a trust."""410        roles = [{'name': n} for n in role_names]411        post_body = {412            'trustor_user_id': trustor_user_id,413            'trustee_user_id': trustee_user_id,414            'project_id': project_id,415            'impersonation': impersonation,416            'roles': roles,417            'expires_at': expires_at418        }419        post_body = json.dumps({'trust': post_body})420        resp, body = self.post('OS-TRUST/trusts', post_body)421        self.expected_success(201, resp.status)422        body = json.loads(body)423        return service_client.ResponseBody(resp, body['trust'])424    def delete_trust(self, trust_id):425        """Deletes a trust."""426        resp, body = self.delete("OS-TRUST/trusts/%s" % trust_id)427        self.expected_success(204, resp.status)428        return service_client.ResponseBody(resp, body)429    def get_trusts(self, trustor_user_id=None, trustee_user_id=None):430        """GET trusts."""431        if trustor_user_id:432            resp, body = self.get("OS-TRUST/trusts?trustor_user_id=%s"433                                  % trustor_user_id)434        elif trustee_user_id:435            resp, body = self.get("OS-TRUST/trusts?trustee_user_id=%s"436                                  % trustee_user_id)437        else:438            resp, body = self.get("OS-TRUST/trusts")439        self.expected_success(200, resp.status)440        body = json.loads(body)441        return service_client.ResponseBodyList(resp, body['trusts'])442    def get_trust(self, trust_id):443        """GET trust."""444        resp, body = self.get("OS-TRUST/trusts/%s" % trust_id)445        self.expected_success(200, resp.status)446        body = json.loads(body)447        return service_client.ResponseBody(resp, body['trust'])448    def get_trust_roles(self, trust_id):449        """GET roles delegated by a trust."""450        resp, body = self.get("OS-TRUST/trusts/%s/roles" % trust_id)451        self.expected_success(200, resp.status)452        body = json.loads(body)453        return service_client.ResponseBodyList(resp, body['roles'])454    def get_trust_role(self, trust_id, role_id):455        """GET role delegated by a trust."""456        resp, body = self.get("OS-TRUST/trusts/%s/roles/%s"457                              % (trust_id, role_id))458        self.expected_success(200, resp.status)459        body = json.loads(body)460        return service_client.ResponseBody(resp, body['role'])461    def check_trust_role(self, trust_id, role_id):462        """HEAD Check if role is delegated by a trust."""463        resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"464                               % (trust_id, role_id))465        self.expected_success(200, resp.status)...rebaselineserver_unittest.py
Source:rebaselineserver_unittest.py  
1# Copyright (C) 2010 Google Inc. All rights reserved.2#3# Redistribution and use in source and binary forms, with or without4# modification, are permitted provided that the following conditions are5# met:6#7#    * Redistributions of source code must retain the above copyright8# notice, this list of conditions and the following disclaimer.9#    * Redistributions in binary form must reproduce the above10# copyright notice, this list of conditions and the following disclaimer11# in the documentation and/or other materials provided with the12# distribution.13#    * Neither the name of Google Inc. nor the names of its14# contributors may be used to endorse or promote products derived from15# this software without specific prior written permission.16#17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.28import unittest29from webkitpy.common.system import filesystem_mock30from webkitpy.layout_tests.port import base31from webkitpy.layout_tests.port.webkit import WebKitPort32from webkitpy.tool.commands import rebaselineserver33from webkitpy.tool.mocktool import MockSCM34class RebaselineTestTest(unittest.TestCase):35    def test_text_rebaseline_update(self):36        self._assertRebaseline(37            test_files=(38                'fast/text-expected.txt',39                'platform/mac/fast/text-expected.txt',40            ),41            results_files=(42                'fast/text-actual.txt',43            ),44            test_name='fast/text.html',45            baseline_target='mac',46            baseline_move_to='none',47            expected_success=True,48            expected_log=[49                'Rebaselining fast/text...',50                '  Updating baselines for mac',51                '    Updated text-expected.txt',52            ])53    def test_text_rebaseline_new(self):54        self._assertRebaseline(55            test_files=(56                'fast/text-expected.txt',57            ),58            results_files=(59                'fast/text-actual.txt',60            ),61            test_name='fast/text.html',62            baseline_target='mac',63            baseline_move_to='none',64            expected_success=True,65            expected_log=[66                'Rebaselining fast/text...',67                '  Updating baselines for mac',68                '    Updated text-expected.txt',69            ])70    def test_text_rebaseline_move_no_op_1(self):71        self._assertRebaseline(72            test_files=(73                'fast/text-expected.txt',74                'platform/win/fast/text-expected.txt',75            ),76            results_files=(77                'fast/text-actual.txt',78            ),79            test_name='fast/text.html',80            baseline_target='mac',81            baseline_move_to='mac-leopard',82            expected_success=True,83            expected_log=[84                'Rebaselining fast/text...',85                '  Updating baselines for mac',86                '    Updated text-expected.txt',87            ])88    def test_text_rebaseline_move_no_op_2(self):89        self._assertRebaseline(90            test_files=(91                'fast/text-expected.txt',92                'platform/mac/fast/text-expected.checksum',93            ),94            results_files=(95                'fast/text-actual.txt',96            ),97            test_name='fast/text.html',98            baseline_target='mac',99            baseline_move_to='mac-leopard',100            expected_success=True,101            expected_log=[102                'Rebaselining fast/text...',103                '  Moving current mac baselines to mac-leopard',104                '    No current baselines to move',105                '  Updating baselines for mac',106                '    Updated text-expected.txt',107            ])108    def test_text_rebaseline_move(self):109        self._assertRebaseline(110            test_files=(111                'fast/text-expected.txt',112                'platform/mac/fast/text-expected.txt',113            ),114            results_files=(115                'fast/text-actual.txt',116            ),117            test_name='fast/text.html',118            baseline_target='mac',119            baseline_move_to='mac-leopard',120            expected_success=True,121            expected_log=[122                'Rebaselining fast/text...',123                '  Moving current mac baselines to mac-leopard',124                '    Moved text-expected.txt',125                '  Updating baselines for mac',126                '    Updated text-expected.txt',127            ])128    def test_text_rebaseline_move_only_images(self):129        self._assertRebaseline(130            test_files=(131                'fast/image-expected.txt',132                'platform/mac/fast/image-expected.txt',133                'platform/mac/fast/image-expected.png',134                'platform/mac/fast/image-expected.checksum',135            ),136            results_files=(137                'fast/image-actual.png',138                'fast/image-actual.checksum',139            ),140            test_name='fast/image.html',141            baseline_target='mac',142            baseline_move_to='mac-leopard',143            expected_success=True,144            expected_log=[145                'Rebaselining fast/image...',146                '  Moving current mac baselines to mac-leopard',147                '    Moved image-expected.checksum',148                '    Moved image-expected.png',149                '  Updating baselines for mac',150                '    Updated image-expected.checksum',151                '    Updated image-expected.png',152            ])153    def test_text_rebaseline_move_already_exist(self):154        self._assertRebaseline(155            test_files=(156                'fast/text-expected.txt',157                'platform/mac-leopard/fast/text-expected.txt',158                'platform/mac/fast/text-expected.txt',159            ),160            results_files=(161                'fast/text-actual.txt',162            ),163            test_name='fast/text.html',164            baseline_target='mac',165            baseline_move_to='mac-leopard',166            expected_success=False,167            expected_log=[168                'Rebaselining fast/text...',169                '  Moving current mac baselines to mac-leopard',170                '    Already had baselines in mac-leopard, could not move existing mac ones',171            ])172    def test_image_rebaseline(self):173        self._assertRebaseline(174            test_files=(175                'fast/image-expected.txt',176                'platform/mac/fast/image-expected.png',177                'platform/mac/fast/image-expected.checksum',178            ),179            results_files=(180                'fast/image-actual.png',181                'fast/image-actual.checksum',182            ),183            test_name='fast/image.html',184            baseline_target='mac',185            baseline_move_to='none',186            expected_success=True,187            expected_log=[188                'Rebaselining fast/image...',189                '  Updating baselines for mac',190                '    Updated image-expected.checksum',191                '    Updated image-expected.png',192            ])193    def _assertRebaseline(self, test_files, results_files, test_name, baseline_target, baseline_move_to, expected_success, expected_log):194        log = []195        test_config = get_test_config(test_files, results_files)196        success = rebaselineserver._rebaseline_test(197            test_name,198            baseline_target,199            baseline_move_to,200            test_config,201            log=lambda l: log.append(l))202        self.assertEqual(expected_log, log)203        self.assertEqual(expected_success, success)204class GetActualResultFilesTest(unittest.TestCase):205    def test(self):206        test_config = get_test_config(result_files=(207            'fast/text-actual.txt',208            'fast2/text-actual.txt',209            'fast/text2-actual.txt',210            'fast/text-notactual.txt',211        ))212        self.assertEqual(213            ('text-actual.txt',),214            rebaselineserver._get_actual_result_files(215                'fast/text.html', test_config))216class GetBaselinesTest(unittest.TestCase):217    def test_no_baselines(self):218        self._assertBaselines(219            test_files=(),220            test_name='fast/missing.html',221            expected_baselines={})222    def test_text_baselines(self):223        self._assertBaselines(224            test_files=(225                'fast/text-expected.txt',226                'platform/mac/fast/text-expected.txt',227            ),228            test_name='fast/text.html',229            expected_baselines={230                'mac': {'.txt': True},231                'base': {'.txt': False},232            })233    def test_image_and_text_baselines(self):234        self._assertBaselines(235            test_files=(236                'fast/image-expected.txt',237                'platform/mac/fast/image-expected.png',238                'platform/mac/fast/image-expected.checksum',239                'platform/win/fast/image-expected.png',240                'platform/win/fast/image-expected.checksum',241            ),242            test_name='fast/image.html',243            expected_baselines={244                'base': {'.txt': True},245                'mac': {'.checksum': True, '.png': True},246                'win': {'.checksum': False, '.png': False},247            })248    def test_extra_baselines(self):249        self._assertBaselines(250            test_files=(251                'fast/text-expected.txt',252                'platform/nosuchplatform/fast/text-expected.txt',253            ),254            test_name='fast/text.html',255            expected_baselines={'base': {'.txt': True}})256    def _assertBaselines(self, test_files, test_name, expected_baselines):257        actual_baselines = rebaselineserver._get_test_baselines(258            test_name, get_test_config(test_files))259        self.assertEqual(expected_baselines, actual_baselines)260def get_test_config(test_files=[], result_files=[]):261    layout_tests_directory = base.Port().layout_tests_dir()262    results_directory = '/WebKitBuild/Debug/layout-test-results'263    mock_filesystem = filesystem_mock.MockFileSystem()264    for file in test_files:265        file_path = mock_filesystem.join(layout_tests_directory, file)266        mock_filesystem.files[file_path] = ''267    for file in result_files:268        file_path = mock_filesystem.join(results_directory, file)269        mock_filesystem.files[file_path] = ''270    class TestMacPort(WebKitPort):271        def __init__(self):272            WebKitPort.__init__(self, filesystem=mock_filesystem)273            self._name = 'mac'274    return rebaselineserver.TestConfig(275        TestMacPort(),276        layout_tests_directory,277        results_directory,278        ('mac', 'mac-leopard', 'win', 'linux'),279        mock_filesystem,...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
