def validate_readthedocs(self, repo):
        if not (repo["owner"]["login"] == "adafruit"
                and repo["name"].startswith("Adafruit_CircuitPython")):
            return []
        if repo["name"] in BUNDLE_IGNORE_LIST:
            return []
        global rtd_subprojects
        if not rtd_subprojects:
            rtd_response = requests.get(
                "https://readthedocs.org/api/v2/project/74557/subprojects/",
                timeout=15)
            if not rtd_response.ok:
                return [ERROR_RTD_SUBPROJECT_FAILED]
            rtd_subprojects = {}
            for subproject in rtd_response.json()["subprojects"]:
                rtd_subprojects[common_funcs.sanitize_url(
                    subproject["repo"])] = subproject

        repo_url = common_funcs.sanitize_url(repo["clone_url"])
        if repo_url not in rtd_subprojects:
            return [ERROR_RTD_SUBPROJECT_MISSING]

        errors = []
        subproject = rtd_subprojects[repo_url]

        if 105398 not in subproject["users"]:
            errors.append(ERROR_RTD_ADABOT_MISSING)

        valid_versions = requests.get(
            "https://readthedocs.org/api/v2/project/{}/active_versions/".
            format(subproject["id"]),
            timeout=15)
        if not valid_versions.ok:
            errors.append(ERROR_RTD_VALID_VERSIONS_FAILED)
        else:
            valid_versions = valid_versions.json()
            latest_release = github.get("/repos/{}/releases/latest".format(
                repo["full_name"]))
            if not latest_release.ok:
                errors.append(ERROR_GITHUB_RELEASE_FAILED)
            # disabling this for now, since it is ignored and always fails
            #else:
            #    if latest_release.json()["tag_name"] not in [tag["verbose_name"] for tag in valid_versions["versions"]]:
            #        errors.append(ERROR_RTD_MISSING_LATEST_RELEASE)

        # There is no API which gives access to a list of builds for a project so we parse the html
        # webpage.
        builds_webpage = requests.get(
            "https://readthedocs.org/projects/{}/builds/".format(
                subproject["slug"]),
            timeout=15)
        if not builds_webpage.ok:
            errors.append(ERROR_RTD_FAILED_TO_LOAD_BUILDS)
        else:
            for line in builds_webpage.text.split("\n"):
                if "<div id=\"build-" in line:
                    build_id = line.split("\"")[1][len("build-"):]
                # We only validate the most recent, latest build. So, break when the first "version
                # latest" found. Its in the page after the build id.
                if "version latest" in line:
                    break
            build_info = requests.get(
                "https://readthedocs.org/api/v2/build/{}/".format(build_id),
                timeout=15)
            if not build_info.ok:
                errors.append(ERROR_RTD_FAILED_TO_LOAD_BUILD_INFO)
            else:
                build_info = build_info.json()
                output_ok = True
                autodoc_ok = True
                sphinx_ok = True
                for command in build_info["commands"]:
                    if command["command"].endswith("_build/html"):
                        for line in command["output"].split("\n"):
                            if "... " in line:
                                _, line = line.split("... ")
                            if "WARNING" in line or "ERROR" in line:
                                if not line.startswith(("WARNING", "ERROR")):
                                    line = line.split(" ", 1)[1]
                                if not line.startswith(RTD_IGNORE_NOTICES):
                                    output_ok = False
                            elif line.startswith("ImportError"):
                                autodoc_ok = False
                            elif line.startswith(
                                    "sphinx.errors") or line.startswith(
                                        "SphinxError"):
                                sphinx_ok = False
                        break
                if not output_ok:
                    errors.append(ERROR_RTD_OUTPUT_HAS_WARNINGS)
                if not autodoc_ok:
                    errors.append(ERROR_RTD_AUTODOC_FAILED)
                if not sphinx_ok:
                    errors.append(ERROR_RTD_SPHINX_FAILED)

        return errors
 def test_comparing_different_urls(self):
     test_a = common_funcs.sanitize_url('http://foo.bar/fooba.git')
     test_b = common_funcs.sanitize_url('http://foo.bar/foobar')
     self.assertNotEqual(test_a, test_b)